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