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-sim.org/
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>
47 #include <utils/common/ToString.h>
54 #include <utils/common/StdDefs.h>
55 #include <utils/geom/GeomHelper.h>
56 #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->getBestLanes();
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 MSRoute* route,
391  const MSVehicleType* type,
392  SUMOReal speedFactor) :
393  MSBaseVehicle(pars, route, type, speedFactor),
394  myWaitingTime(0),
395  myState(0, 0), //
396  myLane(0),
399  myPersonDevice(0),
400  myAcceleration(0),
401  mySignals(0),
402  myAmOnNet(false),
404  myHaveToWaitOnNextLink(false),
405  myCachedPosition(Position::INVALID),
406  myEdgeWeights(0)
407 #ifndef NO_TRACI
408  , myInfluencer(0)
409 #endif
410 {
411  for (std::vector<SUMOVehicleParameter::Stop>::iterator i = pars->stops.begin(); i != pars->stops.end(); ++i) {
412  if (!addStop(*i)) {
413  throw ProcessError("Stop for vehicle '" + pars->id +
414  "' on lane '" + i->lane + "' is too close or not downstream the current route.");
415  }
416  }
417  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = route->getStops().begin(); i != route->getStops().end(); ++i) {
418  if (!addStop(*i)) {
419  throw ProcessError("Stop for vehicle '" + pars->id +
420  "' on lane '" + i->lane + "' is too close or not downstream the current route.");
421  }
422  }
423  const MSLane* const depLane = (*myCurrEdge)->getDepartLane(*this);
424  if (depLane == 0) {
425  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
426  }
427  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > depLane->getVehicleMaxSpeed(this)) {
428  if (type->getSpeedDeviation() > 0 && pars->departSpeed <= type->getSpeedFactor() * depLane->getSpeedLimit() * (2 * type->getSpeedDeviation() + 1.)) {
429  WRITE_WARNING("Choosing new speed factor for vehicle '" + pars->id + "' to match departure speed.");
431  } else {
432  throw ProcessError("Departure speed for vehicle '" + pars->id +
433  "' is too high for the departure lane '" + depLane->getID() + "'.");
434  }
435  }
436  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
437  throw ProcessError("Departure speed for vehicle '" + pars->id +
438  "' is too high for the vehicle type '" + type->getID() + "'.");
439  }
442 }
443 
444 
445 void
448  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
449  if ((*i).myLink != 0) {
450  (*i).myLink->removeApproaching(this);
451  }
452  }
453  leaveLane(reason);
454 }
455 
456 
457 // ------------ interaction with the route
458 bool
460  return myCurrEdge == myRoute->end() - 1 && myStops.empty() && myState.myPos > myArrivalPos - POSITION_EPS;
461 }
462 
463 
464 bool
465 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset) {
466  const MSEdgeVector& edges = newRoute->getEdges();
467  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
468  if (!onInit && !newRoute->contains(*myCurrEdge)) {
469  return false;
470  }
471 
472  // rebuild in-vehicle route information
473  if (onInit) {
474  myCurrEdge = newRoute->begin();
475  } else {
476  myCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);
477  }
478  // check whether the old route may be deleted (is not used by anyone else)
479  newRoute->addReference();
480  myRoute->release();
481  // assign new route
482  myRoute = newRoute;
485  if (!onInit) {
486  getBestLanes(true);
487  }
488  // update arrival definition
490  // save information that the vehicle was rerouted
493  // recheck old stops
494  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
495  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
496  iter = myStops.erase(iter);
497  } else {
498  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
499  ++iter;
500  }
501  }
502  // add new stops
503  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
504  if (!addStop(*i)) {
505  WRITE_WARNING("Stop for vehicle '" + getID() +
506  "' on lane '" + i->lane + "' is too close or not downstream the new route.");
507  }
508  }
509  return true;
510 }
511 
512 
513 bool
514 MSVehicle::willPass(const MSEdge* const edge) const {
515  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
516 }
517 
518 
519 unsigned int
521  return (unsigned int) std::distance(myRoute->begin(), myCurrEdge);
522 }
523 
524 
525 void
526 MSVehicle::resetRoutePosition(unsigned int index) {
527  myCurrEdge = myRoute->begin() + index;
528  // !!! hack
529  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
530 }
531 
532 
533 
536  return _getWeightsStorage();
537 }
538 
539 
542  return _getWeightsStorage();
543 }
544 
545 
548  if (myEdgeWeights == 0) {
550  }
551  return *myEdgeWeights;
552 }
553 
554 
555 // ------------ Interaction with move reminders
556 void
558  // This erasure-idiom works for all stl-sequence-containers
559  // See Meyers: Effective STL, Item 9
560  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
561  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
562 #ifdef _DEBUG
563  if (myTraceMoveReminders) {
564  traceMoveReminder("notifyMove", rem->first, rem->second, false);
565  }
566 #endif
567  rem = myMoveReminders.erase(rem);
568  } else {
569 #ifdef _DEBUG
570  if (myTraceMoveReminders) {
571  traceMoveReminder("notifyMove", rem->first, rem->second, true);
572  }
573 #endif
574  ++rem;
575  }
576  }
577 }
578 
579 
580 void
582  // save the old work reminders, patching the position information
583  // add the information about the new offset to the old lane reminders
584  const SUMOReal oldLaneLength = myLane->getLength();
585  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
586  rem->second += oldLaneLength;
587 #ifdef _DEBUG
588  if (myTraceMoveReminders) {
589  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
590  }
591 #endif
592  }
593  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
594  addReminder(*rem);
595  }
596 }
597 
598 
599 // ------------ Other getter methods
600 SUMOReal
602  if (myLane == 0) {
603  return 0;
604  }
605  const SUMOReal lp = getPositionOnLane();
607  return myLane->getShape().slopeDegreeAtOffset(gp);
608 }
609 
610 
611 Position
612 MSVehicle::getPosition(const SUMOReal offset) const {
613  if (myLane == 0) {
614  return Position::INVALID;
615  }
616  if (isParking()) {
617  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
620  }
621  const bool changingLanes = getLaneChangeModel().isChangingLanes();
622  if (offset == 0. && !changingLanes) {
625  }
626  return myCachedPosition;
627  }
629  if (changingLanes) {
631  Line line = getLaneChangeModel().isLaneChangeMidpointPassed() ? Line(other, result) : Line(result, other);
632  return line.getPositionAtDistance(getLaneChangeModel().getLaneChangeCompletion() * line.length());
633  }
634  return result;
635 }
636 
637 
638 SUMOReal
640  Position p1;
641  Position p2;
642  if (getLaneChangeModel().isChangingLanes()) {
643  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
645  } else {
646  p1 = getPosition();
647  }
649  // vehicle is fully on the new lane (visually)
651  } else {
652  p2 = myFurtherLanes.size() > 0
653  ? myFurtherLanes.back()->geometryPositionAtOffset(myFurtherLanes.back()->getPartialOccupatorEnd())
655  }
656  SUMOReal result = (p1 != p2 ?
657  atan2(p1.x() - p2.x(), p2.y() - p1.y()) * 180. / M_PI :
661  result += getLaneChangeModel().getLaneChangeDirection() * angleOffset;
662  }
663  return result;
664 }
665 
666 
667 // ------------
668 bool
670  Stop stop;
671  stop.lane = MSLane::dictionary(stopPar.lane);
672  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
673  stop.startPos = stopPar.startPos;
674  stop.endPos = stopPar.endPos;
675  stop.duration = stopPar.duration;
676  stop.until = stopPar.until;
677  stop.awaitedPersons = stopPar.awaitedPersons;
678  if (stop.until != -1) {
679  stop.until += untilOffset;
680  }
681  stop.triggered = stopPar.triggered;
682  stop.parking = stopPar.parking;
683  stop.reached = false;
684  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
685  return false;
686  }
687  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
688  MSRouteIterator prevStopEdge = myCurrEdge;
689  SUMOReal prevStopPos = myState.myPos;
690  // where to insert the stop
691  std::list<Stop>::iterator iter = myStops.begin();
692  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
693  if (myStops.size() > 0) {
694  prevStopEdge = myStops.back().edge;
695  prevStopPos = myStops.back().endPos;
696  iter = myStops.end();
697  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
698  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
699  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
700  }
701  }
702  } else {
703  if (stopPar.index == STOP_INDEX_FIT) {
704  while (iter != myStops.end() && (iter->edge < stop.edge ||
705  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
706  prevStopEdge = iter->edge;
707  prevStopPos = iter->endPos;
708  ++iter;
709  }
710  } else {
711  int index = stopPar.index;
712  while (index > 0) {
713  prevStopEdge = iter->edge;
714  prevStopPos = iter->endPos;
715  ++iter;
716  --index;
717  }
718  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
719  }
720  }
721  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
722  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
723  return false;
724  }
725  // David.C:
726  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
728  return false;
729  }
730  if (!hasDeparted() && myCurrEdge == stop.edge) {
731  SUMOReal pos = -1;
733  pos = myParameter->departPos;
734  if (pos < 0.) {
735  pos += (*myCurrEdge)->getLength();
736  }
737  }
739  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
740  }
741  if (pos > stop.endPos) {
742  return false;
743  }
744  }
745  myStops.insert(iter, stop);
746  return true;
747 }
748 
749 
750 bool
752  return !myStops.empty() && myStops.begin()->reached;
753 }
754 
755 
756 bool
758  return isStopped() && myStops.begin()->parking;
759 }
760 
761 
762 bool
764  return isStopped() && myStops.begin()->triggered;
765 }
766 
767 
768 SUMOReal
770  if (myStops.empty()) {
771  // no stops; pass
772  return currentVelocity;
773  }
774  Stop& stop = myStops.front();
775  if (stop.reached) {
776  // ok, we have already reached the next stop
777  // any waiting persons may board now
778  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this);
779  boarded &= stop.awaitedPersons.size() == 0;
780  if (boarded) {
781  if (stop.busstop != 0) {
782  const std::vector<MSPerson*>& persons = myPersonDevice->getPersons();
783  for (std::vector<MSPerson*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
784  stop.busstop->removePerson(*i);
785  }
786  }
787  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
788  stop.triggered = false;
792  }
793  }
794  if (stop.duration <= 0 && !stop.triggered) {
795  // we have waited long enough and fulfilled any passenger-requirements
796  if (stop.busstop != 0) {
797  // inform bus stop about leaving it
798  stop.busstop->leaveFrom(this);
799  }
800  // the current stop is no longer valid
802  myStops.pop_front();
803  // do not count the stopping time towards gridlock time.
804  // Other outputs use an independent counter and are not affected.
805  myWaitingTime = 0;
806  // maybe the next stop is on the same edge; let's rebuild best lanes
807  getBestLanes(true);
808  // continue as wished...
810  } else {
811  // we have to wait some more time
813  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
816  }
817  stop.duration -= DELTA_T;
818  return 0;
819  }
820  } else {
821  // is the next stop on the current lane?
822  if (stop.edge == myCurrEdge) {
823  // get the stopping position
824  SUMOReal endPos = stop.endPos;
825  bool busStopsMustHaveSpace = true;
826  if (stop.busstop != 0) {
827  // on bus stops, we have to wait for free place if they are in use...
828  endPos = stop.busstop->getLastFreePos(*this);
829  if (endPos - 5. < stop.busstop->getBeginLanePosition()) { // !!! explicit offset
830  busStopsMustHaveSpace = false;
831  }
832  }
833  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace
834  && myLane == stop.lane) {
835  // ok, we may stop (have reached the stop)
836  stop.reached = true;
837  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
839  // compute stopping time
840  if (stop.until >= 0) {
841  if (stop.duration == -1) {
843  } else {
845  }
846  }
847  if (stop.busstop != 0) {
848  // let the bus stop know the vehicle
850  }
851  }
852  // decelerate
853  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos());
854  }
855  }
856  return currentVelocity;
857 }
858 
859 
860 void
861 MSVehicle::planMove(const SUMOTime t, const MSVehicle* pred, const SUMOReal lengthsInFront) {
863  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
865 }
866 
867 
868 void
869 MSVehicle::planMoveInternal(const SUMOTime t, const MSVehicle* pred, DriveItemVector& lfLinks) const {
870 #ifdef DEBUG_VEHICLE_GUI_SELECTION
871  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
872  int bla = 0;
873  }
874 #endif
875  // remove information about approaching links, will be reset later in this step
876  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
877  if ((*i).myLink != 0) {
878  (*i).myLink->removeApproaching(this);
879  }
880  }
881  lfLinks.clear();
882 #ifdef HAVE_INTERNAL_LANES
883  myLinkLeaders.clear();
884 #endif
885  //
886  const MSCFModel& cfModel = getCarFollowModel();
887  const SUMOReal vehicleLength = getVehicleType().getLength();
888  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
889  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
890  // vBeg is the initial maximum velocity of this vehicle in this step
891  SUMOReal v = MIN2(maxV, laneMaxV);
892 #ifndef NO_TRACI
893  if (myInfluencer != 0) {
894  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
895  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
896  // !!! recheck - why is it done, here?
897  if (myInfluencer->isVTDControlled()) {
898  return; // !!! temporary
899  }
900  }
901 #endif
902 
903  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
904  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
905  assert(bestLaneConts.size() > 0);
906 #ifdef HAVE_INTERNAL_LANES
907  bool hadNonInternal = false;
908 #else
909  bool hadNonInternal = true;
910 #endif
911  SUMOReal seen = myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
912  SUMOReal seenNonInternal = 0;
913  SUMOReal vLinkPass = MIN2(estimateSpeedAfterDistance(seen, v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
914  unsigned int view = 0;
915  DriveProcessItem* lastLink = 0;
916  SUMOReal gap = 0;
917  if (pred != 0) {
918  if (pred == myLane->getPartialOccupator()) {
920  } else {
922  }
923  }
924  std::pair<const MSVehicle*, SUMOReal> leaderInfo = std::make_pair(pred, gap);
925  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
926  const MSLane* lane = myLane;
927  while (true) {
928  // check leader on lane
929  // leader is given for the first edge only
930  adaptToLeader(leaderInfo, seen, lastLink, lane, v, vLinkPass);
931 
932  // process stops
933  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
934  // we are approaching a stop on the edge; must not drive further
935  const Stop& stop = *myStops.begin();
936  const SUMOReal endPos = stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this);
937  const SUMOReal stopDist = seen + endPos - lane->getLength();
938  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), stopDist);
939  if (lastLink != 0) {
940  lastLink->adaptLeaveSpeed(stopSpeed);
941  }
942  v = MIN2(v, stopSpeed);
943  lfLinks.push_back(DriveProcessItem(v, stopDist));
944  break;
945  }
946 
947  // move to next lane
948  // get the next link used
949  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
950  // check whether the vehicle is on its final edge
951  if (myCurrEdge + view + 1 == myRoute->end()) {
953  myParameter->arrivalSpeed : laneMaxV);
954  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
955  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
956  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
957  v = MIN2(v, va);
958  if (lastLink != 0) {
959  lastLink->adaptLeaveSpeed(va);
960  }
961  lfLinks.push_back(DriveProcessItem(v, seen));
962  break;
963  }
964  // check whether the lane is a dead end
965  if (lane->isLinkEnd(link)) {
966  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
967  if (lastLink != 0) {
968  lastLink->adaptLeaveSpeed(va);
969  }
970  v = MIN2(va, v);
971  lfLinks.push_back(DriveProcessItem(v, seen));
972  break;
973  }
974  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
975  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
976  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
977  // We distinguish 3 cases when determining the point at which a vehicle stops:
978  // - links that require stopping: here the vehicle needs to stop close to the stop line
979  // to ensure it gets onto the junction in the next step. Othwise the vehicle would 'forget'
980  // that it already stopped and need to stop again. This is necessary pending implementation of #999
981  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
982  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
983  // to minimize the time window for passing the junction. If the
984  // vehicle 'decides' to accelerate and cannot enter the junction in
985  // the next step, new foes may appear and cause a collision (see #1096)
986  // - major links: stopping point is irrelevant
987  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
988  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
989  // check whether we need to slow down in order to finish a continuous lane change
990  if (getLaneChangeModel().isChangingLanes()) {
991  if ( // slow down to finish lane change before a turn lane
992  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
993  // slow down to finish lane change before the shadow lane ends
995  (*link)->getViaLaneOrLane()->getParallelLane(-getLaneChangeModel().getLaneChangeDirection()) == 0)) {
996  const SUMOReal timeRemaining = STEPS2TIME((1 - getLaneChangeModel().getLaneChangeCompletion()) * MSGlobals::gLaneChangeDuration);
997  const SUMOReal va = seen / timeRemaining;
998  v = MIN2(va, v);
999  }
1000  }
1001 
1002  const bool setRequest = v > 0; // even if red, if we cannot break we should issue a request
1003  const SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1004  if (yellowOrRed && seen > cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime()) {
1005  // the vehicle is able to brake in front of a yellow/red traffic light
1006  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / vLinkWait), vLinkWait, 0, SUMOTime_MAX, stopDist));
1007  // XXX division by 0 (vLinkWait) should be avoided
1008  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1009  break;
1010  }
1011 
1012 #ifdef HAVE_INTERNAL_LANES
1013  // we want to pass the link but need to check for foes on internal lanes
1014  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
1015  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1016  // the vehicle to enter the junction first has priority
1017  const MSVehicle* leader = (*it).first.first;
1018  if (leader->myLinkLeaders.count(getID()) == 0) {
1019  // leader isn't already following us, now we follow it
1020  myLinkLeaders.insert(leader->getID());
1021  adaptToLeader(it->first, seen, lastLink, lane, v, vLinkPass, it->second);
1022  if (lastLink != 0) {
1023  // we are not yet on the junction with this linkLeader.
1024  // at least we can drive up to the previous link and stop there
1025  v = MAX2(v, lastLink->myVLinkWait);
1026  }
1027  }
1028  }
1029 #endif
1030 
1031  if (lastLink != 0) {
1032  lastLink->adaptLeaveSpeed(laneMaxV);
1033  }
1034  SUMOReal arrivalSpeed = vLinkPass;
1035  SUMOTime arrivalTime;
1036  // vehicles should decelerate when approaching a minor link
1037  if (!(*link)->havePriority() && stopDist > cfModel.getMaxDecel()) {
1038  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1039  arrivalSpeed = cfModel.getMaxDecel() + cfModel.getMaxAccel();
1040  const SUMOReal v1 = MAX2(vLinkWait, arrivalSpeed);
1041  // now + time spent decelerating + time spent at full speed
1042  arrivalTime = t + TIME2STEPS((v1 - arrivalSpeed) / cfModel.getMaxDecel()
1043  + (seen - (v1 * v1 - arrivalSpeed * arrivalSpeed) * 0.5 / cfModel.getMaxDecel()) / vLinkWait);
1044  } else {
1045  const SUMOReal accel = (vLinkPass >= v) ? cfModel.getMaxAccel() : -cfModel.getMaxDecel();
1046  const SUMOReal accelTime = (vLinkPass - v) / accel;
1047  const SUMOReal accelWay = accelTime * (vLinkPass + v) * 0.5;
1048  arrivalTime = t + TIME2STEPS(accelTime + MAX2(SUMOReal(0), seen - accelWay) / vLinkPass);
1049  }
1050  // compute speed, time if vehicle starts braking now
1051  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1052  SUMOReal arrivalSpeedBraking = 0;
1053  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1054  if (seen < cfModel.brakeGap(v)) {
1055  // vehicle cannot come to a complete stop in time
1056  // Because we use a continuous formula for computiing the possible slow-down
1057  // we need to handle the mismatch with the discrete dynamics
1058  if (seen < v) {
1059  arrivalSpeedBraking = arrivalSpeed; // no time left for braking after this step
1060  } else if (2 * (seen - v * cfModel.getHeadwayTime()) * -cfModel.getMaxDecel() + v * v >= 0) {
1061  arrivalSpeedBraking = estimateSpeedAfterDistance(seen - v * cfModel.getHeadwayTime(), v, -cfModel.getMaxDecel());
1062  } else {
1063  arrivalSpeedBraking = cfModel.getMaxDecel();
1064  }
1065  // due to discrecte/continuous mismatch we have to ensure that braking actually helps
1066  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1067  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1068  }
1069  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1070  arrivalTime, arrivalSpeed,
1071  arrivalTimeBraking, arrivalSpeedBraking,
1072  stopDist,
1073  estimateLeaveSpeed(*link, vLinkPass)));
1074 #ifdef HAVE_INTERNAL_LANES
1075  if ((*link)->getViaLane() == 0) {
1076  hadNonInternal = true;
1077  ++view;
1078  }
1079 #else
1080  ++view;
1081 #endif
1082  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1083  if (!setRequest || ((v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD)) {
1084  break;
1085  }
1086  // get the following lane
1087  lane = (*link)->getViaLaneOrLane();
1088  laneMaxV = lane->getVehicleMaxSpeed(this);
1089  // the link was passed
1090  // compute the velocity to use when the link is not blocked by other vehicles
1091  // the vehicle shall be not faster when reaching the next lane than allowed
1092  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1093  v = MIN2(va, v);
1094  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1095  seen += lane->getLength();
1096  leaderInfo = lane->getLastVehicleInformation();
1097  leaderInfo.second = leaderInfo.second + seen - lane->getLength() - getVehicleType().getMinGap();
1098  vLinkPass = MIN2(estimateSpeedAfterDistance(lane->getLength(), v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1099  lastLink = &lfLinks.back();
1100  }
1101 
1102 }
1103 
1104 
1105 void
1106 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1107  const SUMOReal seen, DriveProcessItem* const lastLink,
1108  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1109  SUMOReal distToCrossing) const {
1110  if (leaderInfo.first != 0) {
1111  const MSCFModel& cfModel = getCarFollowModel();
1112  SUMOReal vsafeLeader = 0;
1113  if (leaderInfo.second >= 0) {
1114  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1115  } else {
1116  // the leading, in-lapping vehicle is occupying the complete next lane
1117  // stop before entering this lane
1118  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1119  }
1120  if (distToCrossing >= 0) {
1121  // drive up to the crossing point with the current link leader
1122  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1123  }
1124  if (lastLink != 0) {
1125  lastLink->adaptLeaveSpeed(vsafeLeader);
1126  }
1127  v = MIN2(v, vsafeLeader);
1128  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1129  }
1130 }
1131 
1132 
1133 bool
1135 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1136  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1137  int bla = 0;
1138  }
1139 #endif
1140  // get safe velocities from DriveProcessItems
1141  SUMOReal vSafe = 0; // maximum safe velocity
1142  SUMOReal vSafeMin = 0; // minimum safe velocity
1143  // the distance to a link which should either be crossed this step or in
1144  // front of which we need to stop
1145  SUMOReal vSafeMinDist = 0;
1146  myHaveToWaitOnNextLink = false;
1147 #ifndef NO_TRACI
1148  if (myInfluencer != 0) {
1149  if (myInfluencer->isVTDControlled()) {
1150  return false;
1151  }
1152  }
1153 #endif
1154 
1155  assert(myLFLinkLanes.size() != 0 || (myInfluencer != 0 && myInfluencer->isVTDControlled()));
1156  DriveItemVector::iterator i;
1157  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1158  MSLink* link = (*i).myLink;
1159  // the vehicle must change the lane on one of the next lanes
1160  if (link != 0 && (*i).mySetRequest) {
1161  const LinkState ls = link->getState();
1162  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1163  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1165  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1166  vSafe = (*i).myVLinkWait;
1167  myHaveToWaitOnNextLink = true;
1168  link->removeApproaching(this);
1169  break;
1170  }
1171  //
1172 #ifdef NO_TRACI
1173  const bool influencerPrio = false;
1174 #else
1175  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1176 #endif
1177  const bool opened = yellow || influencerPrio ||
1178  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1181  // vehicles should decelerate when approaching a minor link
1182  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor()) {
1183  if ((*i).myDistance > getCarFollowModel().getMaxDecel()) {
1184  vSafe = (*i).myVLinkWait;
1185  myHaveToWaitOnNextLink = true;
1186  if (ls == LINKSTATE_EQUAL) {
1187  link->removeApproaching(this);
1188  }
1189  break; // could be revalidated
1190  } else {
1191  // past the point of no return. we need to drive fast enough
1192  // to make it across the link. However, minor slowdowns
1193  // should be permissible to follow leading traffic safely
1194  // There is a problem in subsecond simulation: If we cannot
1195  // make it across the minor link in one step, new traffic
1196  // could appear on a major foe link and cause a collision
1197  vSafeMin = MIN2((SUMOReal) DIST2SPEED(myLane->getLength() - getPositionOnLane() + POSITION_EPS), (*i).myVLinkPass);
1198  vSafeMinDist = myLane->getLength() - getPositionOnLane();
1199  }
1200  }
1201  // have waited; may pass if opened...
1202  if (opened) {
1203  vSafe = (*i).myVLinkPass;
1204  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1205  // this vehicle is probably not gonna drive accross the next junction (heuristic)
1206  myHaveToWaitOnNextLink = true;
1207  }
1208  } else {
1209  vSafe = (*i).myVLinkWait;
1210  myHaveToWaitOnNextLink = true;
1211  if (ls == LINKSTATE_EQUAL) {
1212  link->removeApproaching(this);
1213  }
1214  break;
1215  }
1216  } else {
1217  vSafe = (*i).myVLinkWait;
1218  if (vSafe < getSpeed()) {
1219  myHaveToWaitOnNextLink = true;
1220  }
1221  break;
1222  }
1223  }
1224  if (vSafe + NUMERICAL_EPS < vSafeMin) {
1225  // cannot drive across a link so we need to stop before it
1226  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1227  vSafeMin = 0;
1228  myHaveToWaitOnNextLink = true;
1229  }
1230  // XXX braking due to lane-changing is not registered
1231  bool braking = vSafe < getSpeed();
1232  // apply speed reduction due to dawdling / lane changing but ensure minimum save speed
1233  SUMOReal vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1234 
1235  //if (vNext > vSafe) {
1236  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1237  // + toString(vSafe) + ", moving at " + toString(vNext) + " instead. time="
1238  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1239  //}
1240  vNext = MAX2(vNext, (SUMOReal) 0.);
1241 #ifndef NO_TRACI
1242  if (myInfluencer != 0) {
1244  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1245  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1246  if (myInfluencer->isVTDControlled()) {
1247  vNext = 0;
1248  }
1249  }
1250 #endif
1251  // visit waiting time
1252  if (vNext <= SUMO_const_haltingSpeed) {
1254  braking = true;
1255  } else {
1256  myWaitingTime = 0;
1257  }
1258  if (braking) {
1260  } else {
1262  }
1263  // call reminders after vNext is set
1264  const SUMOReal pos = myState.myPos;
1265 
1266  // update position and speed
1268  myState.myPos += SPEED2DIST(vNext);
1269  myState.mySpeed = vNext;
1271  std::vector<MSLane*> passedLanes;
1272  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1273  passedLanes.push_back(*i);
1274  }
1275  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1276  passedLanes.push_back(myLane);
1277  }
1278  bool moved = false;
1279  std::string emergencyReason = " for unknown reasons";
1280  // move on lane(s)
1281  if (myState.myPos <= myLane->getLength()) {
1282  // we are staying at our lane
1283  // there is no need to go over succeeding lanes
1284  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
1285  } else {
1286  // we are moving at least to the next lane (maybe pass even more than one)
1287  if (myCurrEdge != myRoute->end() - 1) {
1288  MSLane* approachedLane = myLane;
1289  // move the vehicle forward
1290  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1292  MSLink* link = (*i).myLink;
1293  // check whether the vehicle was allowed to enter lane
1294  // otherwise it is decelareted and we do not need to test for it's
1295  // approach on the following lanes when a lane changing is performed
1296  // proceed to the next lane
1297  if (link != 0) {
1298  approachedLane = link->getViaLaneOrLane();
1299 #ifndef NO_TRACI
1301 #endif
1302  if (link->getState() == LINKSTATE_TL_RED) {
1303  emergencyReason = " because of a red traffic light";
1304  break;
1305  }
1306 #ifndef NO_TRACI
1307  }
1308 #endif
1309  } else {
1310  emergencyReason = " because there is no connection to the next edge";
1311  approachedLane = 0;
1312  break;
1313  }
1314  if (approachedLane != myLane && approachedLane != 0) {
1315  myState.myPos -= myLane->getLength();
1316  assert(myState.myPos > 0);
1317  enterLaneAtMove(approachedLane);
1318  myLane = approachedLane;
1319  if (getLaneChangeModel().isChangingLanes()) {
1320  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
1321  // abort lane change
1322  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
1323  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1325  }
1326  }
1327  moved = true;
1328  if (approachedLane->getEdge().isVaporizing()) {
1330  break;
1331  }
1332  }
1333  passedLanes.push_back(approachedLane);
1334  }
1335  }
1336  }
1337  // clear previously set information
1338  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1339  (*i)->resetPartialOccupation(this);
1340  }
1341  myFurtherLanes.clear();
1342 
1343  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
1344  myWaitingTime = 0;
1345 // myInfluencer->setVTDControlled(false);
1346  return false;
1347  }
1348 
1349  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
1350  if (myState.myPos > myLane->getLength()) {
1351  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
1352  + emergencyReason
1353  + " (decel=" + toString(myAcceleration - myState.mySpeed)
1354  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1356  myState.mySpeed = 0;
1357  }
1358  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
1359  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1360  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
1361  while (leftLength > 0 && i != passedLanes.rend()) {
1362  myFurtherLanes.push_back(*i);
1363  leftLength -= (*i)->setPartialOccupation(this, leftLength);
1364  ++i;
1365  }
1366  }
1367  getBestLanes();
1368  // bestLanes need to be updated before lane changing starts
1369  if (getLaneChangeModel().isChangingLanes()) {
1371  }
1372  setBlinkerInformation(); // needs updated bestLanes
1373  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1375  }
1376  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1377  return moved;
1378 }
1379 
1380 
1381 SUMOReal
1382 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
1383  SUMOReal lengths = 0;
1384  const MSLane::VehCont& vehs = l->getVehiclesSecure();
1385  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1386  if ((*i)->getSpeed() < SUMO_const_haltingSpeed) {
1387  foundStopped = true;
1388  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
1389  l->releaseVehicles();
1390  return ret;
1391  }
1392  lengths += (*i)->getVehicleType().getLengthWithGap();
1393  }
1394  l->releaseVehicles();
1395  return l->getLength() - lengths;
1396 }
1397 
1398 
1399 void
1400 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
1401 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1402  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1403  int bla = 0;
1404  if (MSNet::getInstance()->getCurrentTimeStep() == 152000) {
1405  bla = 0;
1406  }
1407  }
1408 #endif
1409 #ifdef HAVE_INTERNAL_LANES
1411  bool hadVehicle = false;
1412  SUMOReal seenSpace = -lengthsInFront;
1413 
1414  bool foundStopped = false;
1415  // compute available space until a stopped vehicle is found
1416  // this is the sum of non-interal lane length minus in-between vehicle lenghts
1417  for (unsigned int i = 0; i < lfLinks.size(); ++i) {
1418  // skip unset links
1419  DriveProcessItem& item = lfLinks[i];
1420  if (item.myLink == 0 || foundStopped) {
1421  item.availableSpace = seenSpace;
1422  item.hadVehicle = hadVehicle;
1423  continue;
1424  }
1425  // get the next lane, determine whether it is an internal lane
1426  const MSLane* approachedLane = item.myLink->getViaLane();
1427  if (approachedLane != 0) {
1428  if (item.myLink->isCrossing()/* && item.myLink->willHaveBlockedFoe()*/) {
1429  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
1430  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1431  } else {
1432  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1433  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1434  }
1435  item.availableSpace = seenSpace;
1436  item.hadVehicle = hadVehicle;
1437  continue;
1438  }
1439  approachedLane = item.myLink->getLane();
1440  const MSVehicle* last = approachedLane->getLastVehicle();
1441  if (last == 0) {
1442  last = approachedLane->getPartialOccupator();
1443  if (last != 0) {
1445  item.availableSpace = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
1446  hadVehicle = true;
1448  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1450  if (last->myHaveToWaitOnNextLink) {
1451  foundStopped = true;
1452  }
1453  } else {
1454  seenSpace += approachedLane->getLength();
1455  item.availableSpace = seenSpace;
1456  }
1457  } else {
1458  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
1459  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
1460  const SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
1461  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
1462  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1463  } else {
1464  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
1465  item.availableSpace = seenSpace;
1466  }
1467  if (last->myHaveToWaitOnNextLink) {
1468  foundStopped = true;
1469  }
1470  hadVehicle = true;
1471  }
1472  item.hadVehicle = hadVehicle;
1473  }
1474 
1475 
1476 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1477  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1478  int bla = 0;
1479  }
1480 #endif
1481  // check which links allow continuation and add pass available to the previous item
1482  for (int i = (int)(lfLinks.size() - 1); i > 0; --i) {
1483  DriveProcessItem& item = lfLinks[i - 1];
1484  const bool opened = item.myLink != 0 && (item.myLink->havePriority() ||
1485 #ifndef NO_TRACI
1487 #endif
1488  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
1491  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
1492  if (!opened && item.myLink != 0) {
1493  if (i > 1) {
1494  DriveProcessItem& item2 = lfLinks[i - 2];
1495  if (item2.myLink != 0 && item2.myLink->isCont()) {
1496  allowsContinuation = true;
1497  }
1498  }
1499  }
1500  if (allowsContinuation) {
1501  item.availableSpace = lfLinks[i].availableSpace;
1502  }
1503  }
1504 
1505  // find removalBegin
1506  int removalBegin = -1;
1507  for (unsigned int i = 0; hadVehicle && i < lfLinks.size() && removalBegin < 0; ++i) {
1508  // skip unset links
1509  const DriveProcessItem& item = lfLinks[i];
1510  if (item.myLink == 0) {
1511  continue;
1512  }
1513  /*
1514  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1515  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1516  removalBegin = lastLinkToInternal;
1517  }
1518  */
1519 
1520  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
1521  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1522  SUMOReal impatienceCorrection = 0;
1523  /*
1524  if(item.myLink->getState()==LINKSTATE_MINOR) {
1525  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1526  }
1527  */
1528  if (leftSpace < -impatienceCorrection / 10. && item.myLink->isCrossing()) {
1529  removalBegin = i;
1530  }
1531  //removalBegin = i;
1532  }
1533  }
1534  // abort requests
1535  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1536  while (removalBegin < (int)(lfLinks.size())) {
1538  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
1539  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1540  lfLinks[removalBegin].mySetRequest = false;
1541  }
1542  ++removalBegin;
1543  }
1544  }
1545  }
1546 #else
1547  UNUSED_PARAMETER(lengthsInFront);
1548 #endif
1549  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
1550  if ((*i).myLink != 0) {
1551  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
1552  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((size_t)2); // tie braker
1553  }
1554  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1555  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime());
1556  }
1557  }
1558 }
1559 
1560 
1561 void
1563  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1564  if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) {
1565 #ifdef _DEBUG
1566  if (myTraceMoveReminders) {
1567  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
1568  }
1569 #endif
1570  ++rem;
1571  } else {
1572  if (rem->first->notifyEnter(*this, reason)) {
1573 #ifdef _DEBUG
1574  if (myTraceMoveReminders) {
1575  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
1576  }
1577 #endif
1578  ++rem;
1579  } else {
1580 #ifdef _DEBUG
1581  if (myTraceMoveReminders) {
1582  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
1583  }
1584 #endif
1585  rem = myMoveReminders.erase(rem);
1586  }
1587  }
1588  }
1589 }
1590 
1591 
1592 bool
1593 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1594  myAmOnNet = !onTeleporting;
1595  // vaporizing edge?
1596  /*
1597  if (enteredLane->getEdge().isVaporizing()) {
1598  // yep, let's do the vaporization...
1599  myLane = enteredLane;
1600  return true;
1601  }
1602  */
1603  // move mover reminder one lane further
1604  adaptLaneEntering2MoveReminder(*enteredLane);
1605  // set the entered lane as the current lane
1606  myLane = enteredLane;
1607 
1608  // internal edges are not a part of the route...
1609  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1610  ++myCurrEdge;
1611  }
1612  if (!onTeleporting) {
1614  } else {
1616  // normal move() isn't called so reset position here
1617  myState.myPos = 0;
1619  }
1620  return hasArrived();
1621 }
1622 
1623 
1624 void
1626  myAmOnNet = true;
1627  myLane = enteredLane;
1628  // need to update myCurrentLaneInBestLanes
1629  getBestLanes();
1630  // switch to and activate the new lane's reminders
1631  // keep OldLaneReminders
1632  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1633  addReminder(*rem);
1634  }
1636  /*
1637  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1638  (*i)->resetPartialOccupation(this);
1639  }
1640  myFurtherLanes.clear();
1641  */
1642  if (myState.myPos - getVehicleType().getLength() < 0) {
1643  // we have to rebuild "further lanes"
1644  const MSRoute& route = getRoute();
1646  MSLane* lane = myLane;
1647  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1648  while (i != route.begin() && leftLength > 0) {
1649  /* const MSEdge* const prev = */ *(--i);
1650  lane = lane->getLogicalPredecessorLane();
1651  if (lane == 0) {
1652  break;
1653  }
1654  myFurtherLanes.push_back(lane);
1655  leftLength -= (lane)->setPartialOccupation(this, leftLength);
1656  /*
1657  const std::vector<MSLane::IncomingLaneInfo> &incomingLanes = lane->getIncomingLanes();
1658  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = incomingLanes.begin(); j != incomingLanes.end(); ++j) {
1659  if (&(*j).lane->getEdge() == prev) {
1660  #ifdef HAVE_INTERNAL_LANES
1661  (*j).lane->setPartialOccupation(this, leftLength);
1662  #else
1663  leftLength -= (*j).length;
1664  (*j).lane->setPartialOccupation(this, leftLength);
1665  #endif
1666  leftLength -= (*j).lane->getLength();
1667  break;
1668  }
1669  }
1670  */
1671  }
1672  }
1673 }
1674 
1675 
1676 void
1678  myState = State(pos, speed);
1680  assert(myState.myPos >= 0);
1681  assert(myState.mySpeed >= 0);
1682  myWaitingTime = 0;
1683  myLane = enteredLane;
1684  // set and activate the new lane's reminders
1685  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1686  addReminder(*rem);
1687  }
1688  activateReminders(notification);
1689  std::string msg;
1690  if (MSGlobals::gCheckRoutes && !hasValidRoute(msg)) {
1691  throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
1692  }
1693  myAmOnNet = true;
1694  // build the list of lanes the vehicle is lapping into
1695  SUMOReal leftLength = myType->getLength() - pos;
1696  MSLane* clane = enteredLane;
1697  while (leftLength > 0) {
1698  clane = clane->getLogicalPredecessorLane();
1699  if (clane == 0) {
1700  break;
1701  }
1702  myFurtherLanes.push_back(clane);
1703  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1704  }
1705 }
1706 
1707 
1708 void
1710  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1711  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1712 #ifdef _DEBUG
1713  if (myTraceMoveReminders) {
1714  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
1715  }
1716 #endif
1717  ++rem;
1718  } else {
1719 #ifdef _DEBUG
1720  if (myTraceMoveReminders) {
1721  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
1722  }
1723 #endif
1724  rem = myMoveReminders.erase(rem);
1725  }
1726  }
1727  if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) {
1728  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1729  (*i)->resetPartialOccupation(this);
1730  }
1731  myFurtherLanes.clear();
1732  }
1733  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
1734  myAmOnNet = false;
1735  }
1736 }
1737 
1738 
1741  return *myLaneChangeModel;
1742 }
1743 
1744 
1747  return *myLaneChangeModel;
1748 }
1749 
1750 
1751 const std::vector<MSVehicle::LaneQ>&
1752 MSVehicle::getBestLanes(bool forceRebuild, MSLane* startLane) const {
1753 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1754  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1755  int bla = 0;
1756  myLastBestLanesEdge = 0;
1757  }
1758 #endif
1759 
1760  if (startLane == 0) {
1761  startLane = myLane;
1762  }
1763  assert(startLane != 0);
1764  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
1765  std::vector<LaneQ>& lanes = *myBestLanes.begin();
1766  std::vector<LaneQ>::iterator i;
1767  for (i = lanes.begin(); i != lanes.end(); ++i) {
1768  SUMOReal nextOccupation = 0;
1769  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1770  nextOccupation += (*j)->getBruttoVehLenSum();
1771  }
1772  (*i).nextOccupation = nextOccupation;
1773  if ((*i).lane == startLane) {
1775  }
1776  }
1777  return *myBestLanes.begin();
1778  }
1779  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1780  if (myBestLanes.size() == 0 || forceRebuild) {
1781  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
1782  getBestLanes(true, startLane->getLogicalPredecessorLane());
1783  }
1784  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
1785  return *myBestLanes.begin();
1786  }
1787  // adapt best lanes to fit the current internal edge:
1788  // keep the entries that are reachable from this edge
1789  const MSEdge* nextEdge = startLane->getInternalFollower();
1790  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
1791  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
1792  std::vector<LaneQ>& lanes = *it;
1793  assert(lanes.size() > 0);
1794  if (&(lanes[0].lane->getEdge()) == nextEdge) {
1795  // keep those lanes which are successors of internal lanes from the edge of startLane
1796  std::vector<LaneQ> oldLanes = lanes;
1797  lanes.clear();
1798  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
1799  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
1800  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
1801  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
1802  lanes.push_back(*it_lane);
1803  break;
1804  }
1805  }
1806  }
1807  assert(lanes.size() == startLane->getEdge().getLanes().size());
1808  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
1809  for (int i = 0; i < (int)lanes.size(); ++i) {
1810  if (i + lanes[i].bestLaneOffset < 0) {
1811  lanes[i].bestLaneOffset = -i;
1812  }
1813  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
1814  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
1815  }
1816  assert(i + lanes[i].bestLaneOffset >= 0);
1817  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
1818  if (lanes[i].bestContinuations[0] != 0) {
1819  // patch length of bestContinuation to match expectations (only once)
1820  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
1821  }
1822  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
1823  myCurrentLaneInBestLanes = lanes.begin() + i;
1824  }
1825  assert(&(lanes[i].lane->getEdge()) == nextEdge);
1826  }
1827  myLastBestLanesInternalLane = startLane;
1828  return lanes;
1829  } else {
1830  // remove passed edges
1831  it = myBestLanes.erase(it);
1832  }
1833  }
1834  assert(false); // should always find the next edge
1835  }
1836  // start rebuilding
1837  myLastBestLanesEdge = &startLane->getEdge();
1838  myBestLanes.clear();
1839 
1840  // get information about the next stop
1841  const MSEdge* nextStopEdge = 0;
1842  const MSLane* nextStopLane = 0;
1843  SUMOReal nextStopPos = 0;
1844  if (!myStops.empty()) {
1845  const Stop& nextStop = myStops.front();
1846  nextStopLane = nextStop.lane;
1847  nextStopEdge = &nextStopLane->getEdge();
1848  nextStopPos = nextStop.startPos;
1849  }
1850  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
1851  nextStopEdge = *(myRoute->end() - 1);
1852  nextStopLane = nextStopEdge->getLanes()[myParameter->arrivalLane];
1853  nextStopPos = myArrivalPos;
1854  }
1855  if (nextStopEdge != 0) {
1856  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
1857  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
1858  nextStopPos = MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS));
1859  }
1860 
1861  // go forward along the next lanes;
1862  int seen = 0;
1863  SUMOReal seenLength = 0;
1864  bool progress = true;
1865  for (MSRouteIterator ce = myCurrEdge; progress;) {
1866  std::vector<LaneQ> currentLanes;
1867  const std::vector<MSLane*>* allowed = 0;
1868  const MSEdge* nextEdge = 0;
1869  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
1870  nextEdge = *(ce + 1);
1871  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
1872  }
1873  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
1874  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1875  LaneQ q;
1876  MSLane* cl = *i;
1877  q.lane = cl;
1878  q.bestContinuations.push_back(cl);
1879  q.bestLaneOffset = 0;
1880  q.length = cl->getLength();
1881  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
1882  currentLanes.push_back(q);
1883  }
1884  //
1885  if (nextStopEdge == *ce) {
1886  progress = false;
1887  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
1888  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
1889  (*q).allowsContinuation = false;
1890  (*q).length = nextStopPos;
1891  }
1892  }
1893  }
1894 
1895  myBestLanes.push_back(currentLanes);
1896  ++seen;
1897  seenLength += currentLanes[0].lane->getLength();
1898  ++ce;
1899  progress &= (seen <= 4 || seenLength < 3000);
1900  progress &= seen <= 8;
1901  progress &= ce != myRoute->end();
1902  /*
1903  if(progress) {
1904  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
1905  }
1906  */
1907  }
1908 
1909  // we are examining the last lane explicitly
1910  if (myBestLanes.size() != 0) {
1911  SUMOReal bestLength = -1;
1912  int bestThisIndex = 0;
1913  int index = 0;
1914  std::vector<LaneQ>& last = myBestLanes.back();
1915  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1916  if ((*j).length > bestLength) {
1917  bestLength = (*j).length;
1918  bestThisIndex = index;
1919  }
1920  }
1921  index = 0;
1922  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1923  if ((*j).length < bestLength) {
1924  (*j).bestLaneOffset = bestThisIndex - index;
1925  }
1926  }
1927  }
1928 
1929  // go backward through the lanes
1930  // track back best lane and compute the best prior lane(s)
1931  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
1932  std::vector<LaneQ>& nextLanes = (*(i - 1));
1933  std::vector<LaneQ>& clanes = (*i);
1934  MSEdge& cE = clanes[0].lane->getEdge();
1935  int index = 0;
1936  SUMOReal bestConnectedLength = -1;
1937  SUMOReal bestLength = -1;
1938  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
1939  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
1940  bestConnectedLength = (*j).length;
1941  }
1942  if (bestLength < (*j).length) {
1943  bestLength = (*j).length;
1944  }
1945  }
1946  // compute index of the best lane (highest length and least offset from the best next lane)
1947  int bestThisIndex = 0;
1948  if (bestConnectedLength > 0) {
1949  index = 0;
1950  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1951  LaneQ bestConnectedNext;
1952  bestConnectedNext.length = -1;
1953  if ((*j).allowsContinuation) {
1954  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
1955  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1956  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
1957  bestConnectedNext = *m;
1958  }
1959  }
1960  }
1961  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
1962  (*j).length += bestLength;
1963  } else {
1964  (*j).length += bestConnectedNext.length;
1965  }
1966  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
1967  }
1968  if (clanes[bestThisIndex].length < (*j).length || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))) {
1969  bestThisIndex = index;
1970  }
1971  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
1972  }
1973 
1974  } else {
1975  int bestNextIndex = 0;
1976  int bestDistToNeeded = (int) clanes.size();
1977  index = 0;
1978  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1979  if ((*j).allowsContinuation) {
1980  int nextIndex = 0;
1981  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
1982  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1983  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
1984  bestDistToNeeded = abs((*m).bestLaneOffset);
1985  bestThisIndex = index;
1986  bestNextIndex = nextIndex;
1987  }
1988  }
1989  }
1990  }
1991  }
1992  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
1993  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
1994 
1995  }
1996  // set bestLaneOffset for all lanes
1997  index = 0;
1998  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1999  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))) {
2000  (*j).bestLaneOffset = bestThisIndex - index;
2001  } else {
2002  (*j).bestLaneOffset = 0;
2003  }
2004  }
2005  }
2006 
2007  // update occupancy and current lane index
2008  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
2009  std::vector<LaneQ>::iterator i;
2010  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
2011  SUMOReal nextOccupation = 0;
2012  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
2013  nextOccupation += (*j)->getBruttoVehLenSum();
2014  }
2015  (*i).nextOccupation = nextOccupation;
2016  if ((*i).lane == startLane) {
2018  }
2019  }
2020  return *myBestLanes.begin();
2021 }
2022 
2023 
2024 const std::vector<MSLane*>&
2026  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2027  return myEmptyLaneVector;
2028  }
2029  return (*myCurrentLaneInBestLanes).bestContinuations;
2030 }
2031 
2032 
2033 const std::vector<MSLane*>&
2035  const MSLane* lane = l;
2037  // internal edges are not kept inside the bestLanes structure
2038  lane = lane->getLinkCont()[0]->getLane();
2039  }
2040  if (myBestLanes.size() == 0) {
2041  return myEmptyLaneVector;
2042  }
2043  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
2044  if ((*i).lane == lane) {
2045  return (*i).bestContinuations;
2046  }
2047  }
2048  return myEmptyLaneVector;
2049 }
2050 
2051 
2052 int
2054  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2055  return 0;
2056  } else {
2057  return (*myCurrentLaneInBestLanes).bestLaneOffset;
2058  }
2059 }
2060 
2061 
2062 bool
2064  if (getPositionOnLane() > myLane->getLength()) {
2067  return true;
2068  }
2069  return false;
2070 }
2071 
2072 
2073 SUMOReal
2075 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2076  SUMOReal distance = 1000000.;
2077 #else
2079 #endif
2080  if (isOnRoad() && destEdge != NULL) {
2081  if (&myLane->getEdge() == *myCurrEdge) {
2082  // vehicle is on a normal edge
2083  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
2084  } else {
2085  // vehicle is on inner junction edge
2086  distance = myLane->getLength() - getPositionOnLane();
2087  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
2088  }
2089  }
2090  return distance;
2091 }
2092 
2093 
2094 std::pair<const MSVehicle* const, SUMOReal>
2096  if (myLane == 0) {
2097  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
2098  }
2099  if (dist == 0) {
2101  }
2102  const MSVehicle* lead = 0;
2103  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
2104  MSLane::VehCont::const_iterator pred = std::find(vehs.begin(), vehs.end(), this) + 1;
2105  if (pred != vehs.end()) {
2106  lead = *pred;
2107  }
2109  if (lead != 0) {
2110  return std::make_pair(lead, lead->getPositionOnLane() - lead->getVehicleType().getLength() - getPositionOnLane() - getVehicleType().getMinGap());
2111  }
2112  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
2113  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
2114  return myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
2115 }
2116 
2117 
2118 SUMOReal
2120  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader();
2121  if (leaderInfo.first == 0 || getSpeed() == 0) {
2122  return -1;
2123  }
2124  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
2125 }
2126 
2127 
2128 SUMOReal
2131 }
2132 
2133 
2134 SUMOReal
2137 }
2138 
2139 
2140 SUMOReal
2143 }
2144 
2145 
2146 SUMOReal
2149 }
2150 
2151 
2152 SUMOReal
2155 }
2156 
2157 
2158 SUMOReal
2161 }
2162 
2163 
2164 SUMOReal
2167 }
2168 
2169 
2170 void
2172  if (myPersonDevice == 0) {
2174  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
2175  }
2176  myPersonDevice->addPerson(person);
2177  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
2178  unsigned int numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2179  if (numExpected != 0) {
2180  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
2181  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
2182  // Bus drivers usually do not know the names of the passengers.
2183  myStops.front().awaitedPersons.erase(person->getID());
2184  numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2185  }
2186  if (numExpected == 0) {
2187  myStops.front().duration = 0;
2188  }
2189  }
2190 }
2191 
2192 
2193 unsigned int
2195  unsigned int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
2196  return boarded + myParameter->personNumber;
2197 }
2198 
2199 
2200 void
2203  int state = getLaneChangeModel().getOwnState();
2204  if ((state & LCA_LEFT) != 0) {
2206  } else if ((state & LCA_RIGHT) != 0) {
2208  } else {
2209  const MSLane* lane = getLane();
2210  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
2211  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
2212  switch ((*link)->getDirection()) {
2213  case LINKDIR_TURN:
2214  case LINKDIR_LEFT:
2215  case LINKDIR_PARTLEFT:
2217  break;
2218  case LINKDIR_RIGHT:
2219  case LINKDIR_PARTRIGHT:
2221  break;
2222  default:
2223  break;
2224  }
2225  }
2226  }
2227 
2228 }
2229 
2230 
2231 void
2233  if (myType->amVehicleSpecific()) {
2234  delete myType;
2235  }
2236  myType = type;
2237 }
2238 
2239 unsigned int
2241  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
2242  return (unsigned int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
2243 }
2244 
2245 
2246 #ifndef NO_TRACI
2247 bool
2248 MSVehicle::addTraciStop(MSLane* lane, SUMOReal pos, SUMOReal /*radius*/, SUMOTime duration, bool parking, bool triggered) {
2249  //if the stop exists update the duration
2250  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2251  if (iter->lane == lane && fabs(iter->endPos - pos) < POSITION_EPS) {
2252  if (duration == 0 && !iter->reached) {
2253  myStops.erase(iter);
2254  } else {
2255  iter->duration = duration;
2256  }
2257  return true;
2258  }
2259  }
2260 
2262  newStop.lane = lane->getID();
2263  newStop.busstop = MSNet::getInstance()->getBusStopID(lane, pos);
2264  newStop.startPos = pos - POSITION_EPS;
2265  newStop.endPos = pos;
2266  newStop.duration = duration;
2267  newStop.until = -1;
2268  newStop.triggered = triggered;
2269  newStop.parking = parking;
2270  newStop.index = STOP_INDEX_FIT;
2271  return addStop(newStop);
2272 }
2273 
2274 
2275 bool
2277  Stop& stop = myStops.front();
2278  if (!stop.reached) {
2279  return false;
2280  }
2281  stop.duration = 0;
2282  return true;
2283 }
2284 
2285 
2288  return myStops.front();
2289 }
2290 
2291 
2294  if (myInfluencer == 0) {
2295  myInfluencer = new Influencer();
2296  }
2297  return *myInfluencer;
2298 }
2299 
2300 
2301 SUMOReal
2303  if (myInfluencer != 0) {
2304  return myInfluencer->getOriginalSpeed();
2305  }
2306  return myState.mySpeed;
2307 }
2308 
2309 
2310 int
2312  if (hasInfluencer()) {
2314  MSNet::getInstance()->getCurrentTimeStep(),
2315  myLane->getEdge(),
2316  getLaneIndex(),
2317  state);
2318  }
2319  return state;
2320 }
2321 #endif
2322 
2323 
2324 void
2327  // here starts the vehicle internal part (see loading)
2328  std::vector<int> internals;
2329  internals.push_back(myDeparture);
2330  internals.push_back((int)distance(myRoute->begin(), myCurrEdge));
2331  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
2334  out.closeTag();
2335 }
2336 
2337 
2338 void
2339 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
2340  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
2341  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
2342  }
2343  unsigned int routeOffset;
2344  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
2345  bis >> myDeparture;
2346  bis >> routeOffset;
2347  if (hasDeparted()) {
2348  myDeparture -= offset;
2349  myCurrEdge += routeOffset;
2350  }
2353  // no need to reset myCachedPosition here since state loading happens directly after creation
2354 }
2355 
2356 
2357 /****************************************************************************/
void resetRoutePosition(unsigned int index)
Definition: MSVehicle.cpp:526
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:800
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1099
The link is a partial left direction.
const std::string & getID() const
returns the person id
Definition: MSPerson.cpp:524
#define DIST2SPEED(x)
Definition: SUMOTime.h:57
virtual const std::vector< LaneQ > & getBestLanes(bool forceRebuild=false, MSLane *startLane=0) const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1752
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
const MSVehicleType * myType
This Vehicle's type.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:2232
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:245
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:1593
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:452
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:920
SUMOReal getMaxSpeed() const
Get vehicle'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:108
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
void removePerson(MSPerson *p)
Definition: MSBusStop.h:147
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:45
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:1233
MoveReminderCont myMoveReminders
Current lane'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:1098
LaneChangeMode
modes for resolving conflicts between external control (traci) and vehicle control over lane changing...
Definition: MSVehicle.h:756
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1096
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1121
Position positionAtOffset(SUMOReal pos) const
Returns the position at the given length.
const MSEdge * getInternalFollower() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:818
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1101
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's car following model definition.
Definition: MSVehicle.h:531
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1115
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1091
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:2287
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:1185
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.cpp:136
bool resumeFromStopping()
Definition: MSVehicle.cpp:2276
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1124
bool hasInfluencer() const
Definition: MSVehicle.h:1036
SUMOTime duration
The stopping duration.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
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'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:2201
#define M_PI
Definition: angles.h:37
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1177
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1112
MSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:59
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2302
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:974
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:362
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle's safe speed (no dawdling)
SUMOReal getLength() const
Returns the lane's length.
Definition: MSLane.h:370
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:612
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:459
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:58
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:61
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
SUMOReal getLength() const
Get vehicle's length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1011
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:465
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:853
const MSEdgeVector & getEdges() const
Definition: MSRoute.h:122
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2141
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:571
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:154
T MAX2(T a, T b)
Definition: StdDefs.h:71
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:86
vehicle doesn't want to change
Definition: MSVehicle.h:127
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2194
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:764
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'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:1191
SUMOTime until
The time at which the vehicle may continue its journey.
SUMOReal mySpeed
the stored speed
Definition: MSVehicle.h:117
const int STOP_INDEX_FIT
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:551
This is an uncontrolled, right-before-left link.
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:2129
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:1134
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:2095
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:283
const SUMOVehicleParameter * myParameter
This Vehicle's parameter.
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:264
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:321
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:57
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1126
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:769
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:210
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:1297
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:38
std::string getBusStopID(const MSLane *lane, const SUMOReal pos) const
Returns the bus stop close to the given position.
Definition: MSNet.cpp:699
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:63
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:1625
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:950
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
SUMOReal getBeginLanePosition() const
Returns the begin position of this bus stop.
Definition: MSBusStop.cpp:65
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:567
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:1740
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1236
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's car following model definition (const version)
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:722
std::vector< Stop > stops
List of the stops the vehicle will make.
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle's end.
Definition: MSLane.h:261
void enter(SUMOVehicle *what, SUMOReal beg, SUMOReal end)
Called if a vehicle enters this stop.
Definition: MSBusStop.cpp:77
The vehicles starts to stop.
Definition: MSNet.h:435
SUMOReal slopeDegreeAtOffset(SUMOReal pos) const
Returns the slope at the given length.
The state of a link.
static SUMOReal computeFuel(SUMOEmissionClass c, double v, double a, double slope)
Returns the amount of consumed fuel given the vehicle type and state (in ml/s)
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:1677
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
static SUMOReal computeCO2(SUMOEmissionClass c, double v, double a, double slope)
Returns the amount of emitted CO2 given the vehicle type and state (in mg/s)
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:73
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:1400
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.cpp:568
Left blinker lights are switched on.
Definition: MSVehicle.h:724
MSLane * getLogicalPredecessorLane() const
Definition: MSLane.cpp:1224
#define max(a, b)
Definition: polyfonts.c:61
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's reaction time.
Definition: MSCFModel.h:213
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
SUMOReal getSpeedDeviation() const
Returns this type's speed deviation.
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 leader and the distance to him.
Definition: MSLane.cpp:1164
The vehicle got a new route.
Definition: MSNet.h:429
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:557
vehicle want's to change to right lane
Definition: MSVehicle.h:131
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:100
bool addTraciStop(MSLane *lane, SUMOReal pos, SUMOReal radius, SUMOTime duration, bool parking, bool triggered)
Definition: MSVehicle.cpp:2248
static bool gCheckRoutes
Definition: MSGlobals.h:79
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.
static SUMOReal computeNOx(SUMOEmissionClass c, double v, double a, double slope)
Returns the amount of emitted NOx given the vehicle type and state (in mg/s)
std::vector< const MSEdge * > MSEdgeVector
Definition: MSPerson.h:53
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:125
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle's current lane and their successors...
Definition: MSVehicle.cpp:2025
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:514
void addPerson(MSPerson *person)
Add a passenger.
A list of positions.
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:511
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
Position myCachedPosition
Definition: MSVehicle.h:1128
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:263
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:555
static SUMOReal gap(SUMOReal predPos, SUMOReal predLength, SUMOReal pos)
Uses the given values to compute the brutto-gap.
Definition: MSVehicle.h:212
bool triggered
whether an arriving person lets the vehicle continue
std::list< Stop > myStops
The vehicle's list of stops.
Definition: MSVehicle.h:1106
const int STOP_INDEX_END
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:104
static SUMOReal computeHC(SUMOEmissionClass c, double v, double a, double slope)
Returns the amount of emitted HC given the vehicle type and state (in mg/s)
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:751
std::pair< MSVehicle *, SUMOReal > getLastVehicleInformation() const
Returns the last vehicle which is still on the lane.
Definition: MSLane.cpp:635
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:1170
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1094
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:932
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
Influencer * myInfluencer
An instance of a velocity/lane influencing instance; built in "getInfluencer".
Definition: MSVehicle.h:1240
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1102
SUMOReal getSpaceTillLastStanding(const MSLane *l, bool &foundStopped) const
Definition: MSVehicle.cpp:1382
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:563
Definition: Line.h:51
bool isRoundabout() const
Definition: MSEdge.h:448
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:270
T MIN2(T a, T b)
Definition: StdDefs.h:65
The link is a (hard) right direction.
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap2pred) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling) ...
#define POSITION_EPS
Definition: config.h:186
SUMOReal getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:362
The brake lights are on.
Definition: MSVehicle.h:728
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSVehicle.h:1204
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:2339
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:446
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:70
const std::vector< MSPerson * > & getPersons() const
Returns the list of persons using this vehicle.
static MTRand myVehicleParamsRNG
A random number generator used to choose from vtype/route distributions and computing the speed facto...
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
Definition: MSCFModel.h:165
MSBusStop * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:693
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:297
virtual MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:932
void leaveFrom(SUMOVehicle *what)
Called if a vehicle leaves this stop.
Definition: MSBusStop.cpp:93
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuouss lane change.
bool addStop(const SUMOVehicleParameter::Stop &stopPar, SUMOTime untilOffset=0)
Adds a stop.
Definition: MSVehicle.cpp:669
SUMOReal getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSLane.h:328
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1088
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:52
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:97
The link is a partial right direction.
SUMOReal computeChosenSpeedDeviation(MTRand &rng, const SUMOReal minDevFactor=0.2) const
Computes and returns the speed deviation.
virtual SUMOReal getHeadwayTime() const
Get the driver's reaction time [s].
Definition: MSCFModel.h:184
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:99
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:757
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:2165
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:86
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:2325
void planMoveInternal(const SUMOTime t, const MSVehicle *pred, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:869
SUMOReal getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.h:960
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:2147
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:84
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:547
Influencer()
Constructor.
Definition: MSVehicle.cpp:149
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:1709
SUMOReal getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition: MSCFModel.h:157
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:2153
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2135
SUMOReal getSpeedFactor() const
Returns this type's speed factor.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_UNKNOWN) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:213
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:829
vehicle want's to change to left lane
Definition: MSVehicle.h:129
The action is needed to follow the route (navigational lc)
SUMOReal myChosenSpeedFactor
A precomputed factor by which the driver wants to be faster than the speed limit. ...
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:204
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2293
#define BUS_STOP_OFFSET
Definition: MSVehicle.cpp:95
Structure representing possible vehicle parameter.
SUMOReal length() const
Definition: Line.cpp:183
virtual SUMOReal freeSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal seen, SUMOReal maxSpeed) const
Computes the vehicle's safe speed without a leader.
Definition: MSCFModel.cpp:92
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:80
bool getEmergencyBrakeRedLight() const
Returns whether red lights shall be a reason to brake.
Definition: MSVehicle.h:946
#define SUMOTime_MAX
Definition: SUMOTime.h:44
static SUMOReal computeCO(SUMOEmissionClass c, double v, double a, double slope)
Returns the amount of emitted CO given the vehicle type and state (in mg/s)
virtual VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting...
Definition: MSCFModel.h:148
SUMOReal getSlope() const
Returns the slope of the road at vehicle's position.
Definition: MSVehicle.cpp:601
virtual MSPersonControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:611
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:2063
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:1118
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)
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:573
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2159
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:1106
The action is due to the default of keeping right "Rechtsfahrgebot".
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:94
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:565
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:553
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge)
Definition: MSVehicle.cpp:2074
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:53
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:437
SUMOReal getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:291
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's state change.
Definition: MSNet.cpp:677
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:335
SUMOReal myPos
the stored position
Definition: MSVehicle.h:110
MSBusStop * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:557
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:763
std::vector< DriveProcessItem > DriveItemVector
Definition: MSVehicle.h:1182
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:861
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:323
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:561
void move2side(SUMOReal amount)
vehicle want's to keep the current lane
Definition: MSVehicle.h:133
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:70
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:215
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:783
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:775
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1103
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:159
#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:998
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:105
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle'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:336
SUMOEmissionClass getEmissionClass() const
Get this vehicle type's emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:328
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:2311
void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
Definition: MSVehicle.cpp:1562
The edge is an internal edge.
Definition: MSEdge.h:90
SUMOReal getTimeGap() const
Returns the time gap in seconds to the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2119
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:82
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane's move reminders.
Definition: MSLane.h:150
void addPerson(MSPerson *person)
Adds a passenger.
Definition: MSVehicle.cpp:2171
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:559
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's internal edge travel times/efforts container.
Definition: MSVehicle.cpp:535
std::vector< MSDevice * > myDevices
The devices this vehicle has.
void adaptLaneEntering2MoveReminder(const MSLane &enteredLane)
Adapts the vehicle's entering of a new lane.
Definition: MSVehicle.cpp:581
unsigned int size() const
Return the number of passengers.
Back-at-zero position.
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:520
static SUMOReal computePMx(SUMOEmissionClass c, double v, double a, double slope)
Returns the amount of emitted PMx given the vehicle type and state (in mg/s)
Interface for lane-change models.
MSDevice_Person * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1109
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:2053
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:74
std::string id
The vehicle's id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:569
static const Position INVALID
Definition: Position.h:252
The vehicle is being teleported.
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
SUMOReal getAngle() const
Returns the vehicle's direction in degrees.
Definition: MSVehicle.cpp:639
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:2240