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