SUMO - Simulation of Urban MObility
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
17 // Representation of a vehicle in the micro simulation
18 /****************************************************************************/
19 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
20 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
21 /****************************************************************************/
22 //
23 // This file is part of SUMO.
24 // SUMO is free software: you can redistribute it and/or modify
25 // it under the terms of the GNU General Public License as published by
26 // the Free Software Foundation, either version 3 of the License, or
27 // (at your option) any later version.
28 //
29 /****************************************************************************/
30 
31 // ===========================================================================
32 // included modules
33 // ===========================================================================
34 #ifdef _MSC_VER
35 #include <windows_config.h>
36 #else
37 #include <config.h>
38 #endif
39 
40 #include <iostream>
41 #include <cassert>
42 #include <cmath>
43 #include <cstdlib>
44 #include <algorithm>
45 #include <map>
46 #include <utils/common/ToString.h>
53 #include <utils/common/StdDefs.h>
54 #include <utils/geom/GeomHelper.h>
60 #include <microsim/MSGlobals.h>
61 #include "MSStoppingPlace.h"
63 #include "MSEdgeWeightsStorage.h"
65 #include "MSMoveReminder.h"
67 #include "MSPersonControl.h"
68 #include "MSContainer.h"
69 #include "MSContainerControl.h"
70 #include "MSLane.h"
71 #include "MSJunction.h"
72 #include "MSVehicle.h"
73 #include "MSEdge.h"
74 #include "MSVehicleType.h"
75 #include "MSNet.h"
76 #include "MSRoute.h"
77 #include "MSLinkCont.h"
78 
79 #ifdef CHECK_MEMORY_LEAKS
80 #include <foreign/nvwa/debug_new.h>
81 #endif // CHECK_MEMORY_LEAKS
82 
83 // enable here and in utils/gui/globjects/GUIGLObjectPopupMenu.cpp
84 //#define DEBUG_VEHICLE_GUI_SELECTION 1
85 
86 #define BUS_STOP_OFFSET 0.5
87 
88 #define CRLL_LOOK_AHEAD 5
89 
90 // @todo Calibrate with real-world values / make configurable
91 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
92 
93 // ===========================================================================
94 // static value definitions
95 // ===========================================================================
96 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
97 std::vector<MSTransportable*> MSVehicle::myEmptyTransportableVector;
98 
99 
100 // ===========================================================================
101 // method definitions
102 // ===========================================================================
103 /* -------------------------------------------------------------------------
104  * methods of MSVehicle::State
105  * ----------------------------------------------------------------------- */
107  myPos = state.myPos;
108  mySpeed = state.mySpeed;
109 }
110 
111 
114  myPos = state.myPos;
115  mySpeed = state.mySpeed;
116  return *this;
117 }
118 
119 
120 bool
122  return (myPos != state.myPos ||
123  mySpeed != state.mySpeed);
124 }
125 
126 
127 SUMOReal
129  return myPos;
130 }
131 
132 
134  myPos(pos), mySpeed(speed) {}
135 
136 
137 
138 /* -------------------------------------------------------------------------
139  * methods of MSVehicle::WaitingTimeCollector
140  * ----------------------------------------------------------------------- */
141 
143 
145 
150  return *this;
151 }
152 
155  myWaitingIntervals.clear();
156  passTime(t, true);
157  return *this;
158 }
159 
160 SUMOTime
162  assert(memorySpan <= myMemorySize);
163  if (memorySpan == -1) {
164  memorySpan = myMemorySize;
165  }
166  SUMOTime totalWaitingTime = 0;
167  for (waitingIntervalList::const_iterator i = myWaitingIntervals.begin(); i != myWaitingIntervals.end(); i++) {
168  if (i->second >= memorySpan) {
169  if (i->first >= memorySpan) {
170  break;
171  } else {
172  totalWaitingTime += memorySpan - i->first;
173  }
174  } else {
175  totalWaitingTime += i->second - i->first;
176  }
177  }
178  return totalWaitingTime;
179 }
180 
181 void
183  waitingIntervalList::iterator i = myWaitingIntervals.begin();
184  waitingIntervalList::iterator end = myWaitingIntervals.end();
185  bool startNewInterval = i == end || (i->first != 0);
186  while (i != end) {
187  i->first += dt;
188  if (i->first >= myMemorySize) {
189  break;
190  }
191  i->second += dt;
192  i++;
193  }
194 
195  // remove intervals beyond memorySize
196  waitingIntervalList::iterator::difference_type d = std::distance(i, end);
197  while (d > 0) {
198  myWaitingIntervals.pop_back();
199  d--;
200  }
201 
202  if (!waiting) {
203  return;
204  } else if (!startNewInterval) {
205  myWaitingIntervals.begin()->first = 0;
206  } else {
207  myWaitingIntervals.push_front(std::make_pair(0, dt));
208  }
209  return;
210 }
211 
212 
213 
214 
215 
216 /* -------------------------------------------------------------------------
217  * methods of MSVehicle::Influencer
218  * ----------------------------------------------------------------------- */
219 #ifndef NO_TRACI
221  mySpeedAdaptationStarted(true),
222  myConsiderSafeVelocity(true),
223  myConsiderMaxAcceleration(true),
224  myConsiderMaxDeceleration(true),
225  myRespectJunctionPriority(true),
226  myEmergencyBrakeRedLight(true),
227  myLastVTDAccess(-TIME2STEPS(20)),
228  myStrategicLC(LC_NOCONFLICT),
229  myCooperativeLC(LC_NOCONFLICT),
230  mySpeedGainLC(LC_NOCONFLICT),
231  myRightDriveLC(LC_NOCONFLICT),
232  myTraciLaneChangePriority(LCP_URGENT) {
233 }
234 
235 
237 
238 
239 void
240 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
242  mySpeedTimeLine = speedTimeLine;
243 }
244 
245 
246 void
247 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, unsigned int> >& laneTimeLine) {
248  myLaneTimeLine = laneTimeLine;
249 }
250 
251 
252 SUMOReal
254  // keep original speed
255  myOriginalSpeed = speed;
256  // remove leading commands which are no longer valid
257  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
258  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
259  }
260  // do nothing if the time line does not apply for the current time
261  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
262  return speed;
263  }
264  // compute and set new speed
266  mySpeedTimeLine[0].second = speed;
268  }
269  currentTime += DELTA_T;
270  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
271  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
273  speed = MIN2(speed, vSafe);
274  }
276  speed = MIN2(speed, vMax);
277  }
279  speed = MAX2(speed, vMin);
280  }
281  return speed;
282 }
283 
284 
285 int
286 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const unsigned int currentLaneIndex, int state) {
287  // remove leading commands which are no longer valid
288  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
289  myLaneTimeLine.erase(myLaneTimeLine.begin());
290  }
291  ChangeRequest changeRequest = REQUEST_NONE;
292  // do nothing if the time line does not apply for the current time
293  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
294  const unsigned int destinationLaneIndex = myLaneTimeLine[1].second;
295  if (destinationLaneIndex < (unsigned int)currentEdge.getLanes().size()) {
296  if (currentLaneIndex > destinationLaneIndex) {
297  changeRequest = REQUEST_RIGHT;
298  } else if (currentLaneIndex < destinationLaneIndex) {
299  changeRequest = REQUEST_LEFT;
300  } else {
301  changeRequest = REQUEST_HOLD;
302  }
303  }
304  }
305  // check whether the current reason shall be canceled / overridden
306  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
307  // flags for the current reason
308  LaneChangeMode mode = LC_NEVER;
309  if ((state & LCA_STRATEGIC) != 0) {
310  mode = myStrategicLC;
311  } else if ((state & LCA_COOPERATIVE) != 0) {
312  mode = myCooperativeLC;
313  } else if ((state & LCA_SPEEDGAIN) != 0) {
314  mode = mySpeedGainLC;
315  } else if ((state & LCA_KEEPRIGHT) != 0) {
316  mode = myRightDriveLC;
317  } else if ((state & LCA_TRACI) != 0) {
318  mode = LC_NEVER;
319  } else {
320  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
321  }
322  if (mode == LC_NEVER) {
323  // cancel all lcModel requests
324  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
325  state &= ~LCA_URGENT;
326  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
327  if (
328  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
329  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
330  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
331  // cancel conflicting lcModel request
332  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
333  state &= ~LCA_URGENT;
334  }
335  } else if (mode == LC_ALWAYS) {
336  // ignore any TraCI requests
337  return state;
338  }
339  }
340  // apply traci requests
341  if (changeRequest == REQUEST_NONE) {
342  return state;
343  } else {
344  state |= LCA_TRACI;
345  // security checks
347  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
348  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
349  }
350  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
351  state |= LCA_URGENT;
352  }
353  switch (changeRequest) {
354  case REQUEST_HOLD:
355  return state | LCA_STAY;
356  case REQUEST_LEFT:
357  return state | LCA_LEFT;
358  case REQUEST_RIGHT:
359  return state | LCA_RIGHT;
360  default:
361  throw ProcessError("should not happen");
362  }
363  }
364 }
365 
366 
367 SUMOReal
369  assert(myLaneTimeLine.size() >= 2);
370  assert(currentTime >= myLaneTimeLine[0].first);
371  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
372 }
373 
374 
375 void
377  myConsiderSafeVelocity = value;
378 }
379 
380 
381 void
384 }
385 
386 
387 void
390 }
391 
392 
393 void
396 }
397 
398 
399 void
401  myEmergencyBrakeRedLight = value;
402 }
403 
404 
405 void
407  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
408  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
409  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
410  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
411  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
412 }
413 
414 
415 void
417  myVTDLane = l;
418  myVTDPos = pos;
419  myVTDAngle = angle;
420  myVTDEdgeOffset = edgeOffset;
421  myVTDRoute = route;
422  myLastVTDAccess = t;
423 }
424 
425 
426 bool
429 }
430 
431 
432 bool
434  return myLastVTDAccess >= t - TIME2STEPS(10);
435 }
436 
437 void
441  if (myVTDRoute.size() != 0) {
442  v->replaceRouteEdges(myVTDRoute, true);
443  }
445  if (myVTDPos > myVTDLane->getLength()) {
447  }
449  v->updateBestLanes();
450  // inverse of GeomHelper::naviDegree
451  v->setAngle(M_PI / 2. - DEG2RAD(myVTDAngle));
452 }
453 
454 
455 SUMOReal
457  const SUMOReal dist = veh->getDistanceToPosition(myVTDPos, &myVTDLane->getEdge());
458  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
459  return oldSpeed;
460  } else {
461  return DIST2SPEED(dist);
462  }
463 }
464 
465 SUMOReal
467  const SUMOReal dist = veh->getDistanceToPosition(myVTDPos, &myVTDLane->getEdge());
468  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
469  return 0;
470  } else {
471  return dist;
472  }
473 }
474 
475 #endif
476 
477 
478 /* -------------------------------------------------------------------------
479  * MSVehicle-methods
480  * ----------------------------------------------------------------------- */
482  delete myEdgeWeights;
483  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
484  (*i)->resetPartialOccupation(this);
485  }
486  delete myLaneChangeModel; // still needed when calling resetPartialOccupation (getShadowLane)
487  myFurtherLanes.clear();
488  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
489  if ((*i).myLink != 0) {
490  (*i).myLink->removeApproaching(this);
491  }
492  }
493  //
494  if (myType->amVehicleSpecific()) {
495  delete myType;
496  }
497 
498  delete myCFVariables;
499 
500 #ifndef NO_TRACI
501  delete myInfluencer;
502 #endif
503 }
504 
505 
507  const MSVehicleType* type, const SUMOReal speedFactor) :
508  MSBaseVehicle(pars, route, type, speedFactor),
509  myWaitingTime(0),
511  myState(0, 0), //
512  myLane(0),
515  myPersonDevice(0),
517  myAcceleration(0),
518  mySignals(0),
519  myAmOnNet(false),
522  myHaveToWaitOnNextLink(false),
523  myAngle(0),
524  myCachedPosition(Position::INVALID),
525  myEdgeWeights(0)
526 #ifndef NO_TRACI
527  , myInfluencer(0)
528 #endif
529 {
530  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
531  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
532  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
533  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
534  }
535  } else {
536  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
537  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
538  }
539  }
540  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
541  throw ProcessError("Departure speed for vehicle '" + pars->id +
542  "' is too high for the vehicle type '" + type->getID() + "'.");
543  }
544  }
547 }
548 
549 
550 void
554  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
555  if ((*i).myLink != 0) {
556  (*i).myLink->removeApproaching(this);
557  }
558  }
559  leaveLane(reason);
560 }
561 
562 
563 // ------------ interaction with the route
564 bool
566  return myCurrEdge == myRoute->end() - 1 && (myStops.empty() || myStops.front().edge != myCurrEdge)
568 }
569 
570 
571 bool
572 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset) {
573  const ConstMSEdgeVector& edges = newRoute->getEdges();
574  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
575  if (!onInit && !newRoute->contains(*myCurrEdge)) {
576  return false;
577  }
578 
579  // rebuild in-vehicle route information
580  if (onInit) {
581  myCurrEdge = newRoute->begin();
582  } else {
583  myCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);
584  }
585  // check whether the old route may be deleted (is not used by anyone else)
586  newRoute->addReference();
587  myRoute->release();
588  // assign new route
589  myRoute = newRoute;
592  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
593  // update arrival definition
595  // save information that the vehicle was rerouted
598  // recheck old stops
599  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
600  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
601  iter = myStops.erase(iter);
602  } else {
603  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
604  ++iter;
605  }
606  }
607  // add new stops
608  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
609  std::string error;
610  addStop(*i, error);
611  if (error != "") {
612  WRITE_WARNING(error);
613  }
614  }
615  return true;
616 }
617 
618 
619 bool
620 MSVehicle::willPass(const MSEdge* const edge) const {
621  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
622 }
623 
624 
625 unsigned int
627  return (unsigned int) std::distance(myRoute->begin(), myCurrEdge);
628 }
629 
630 
631 void
632 MSVehicle::resetRoutePosition(unsigned int index) {
633  myCurrEdge = myRoute->begin() + index;
634  // !!! hack
635  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
636 }
637 
638 
639 
642  return _getWeightsStorage();
643 }
644 
645 
648  return _getWeightsStorage();
649 }
650 
651 
654  if (myEdgeWeights == 0) {
656  }
657  return *myEdgeWeights;
658 }
659 
660 
661 // ------------ Interaction with move reminders
662 void
664  // This erasure-idiom works for all stl-sequence-containers
665  // See Meyers: Effective STL, Item 9
666  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
667  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
668 #ifdef _DEBUG
669  if (myTraceMoveReminders) {
670  traceMoveReminder("notifyMove", rem->first, rem->second, false);
671  }
672 #endif
673  rem = myMoveReminders.erase(rem);
674  } else {
675 #ifdef _DEBUG
676  if (myTraceMoveReminders) {
677  traceMoveReminder("notifyMove", rem->first, rem->second, true);
678  }
679 #endif
680  ++rem;
681  }
682  }
683 }
684 
685 
686 void
688  // save the old work reminders, patching the position information
689  // add the information about the new offset to the old lane reminders
690  const SUMOReal oldLaneLength = myLane->getLength();
691  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
692  rem->second += oldLaneLength;
693 #ifdef _DEBUG
694  if (myTraceMoveReminders) {
695  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
696  }
697 #endif
698  }
699  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
700  addReminder(*rem);
701  }
702 }
703 
704 
705 // ------------ Other getter methods
706 SUMOReal
708  if (myLane == 0) {
709  return 0;
710  }
711  const SUMOReal lp = getPositionOnLane();
713  return myLane->getShape().slopeDegreeAtOffset(gp);
714 }
715 
716 
717 Position
718 MSVehicle::getPosition(const SUMOReal offset) const {
719  if (myLane == 0) {
720  return Position::INVALID;
721  }
722  if (isParking()) {
723  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
726  }
727  const bool changingLanes = getLaneChangeModel().isChangingLanes();
728  if (offset == 0. && !changingLanes) {
731  }
732  return myCachedPosition;
733  }
735  if (changingLanes) {
737  const SUMOReal dist = getLaneChangeModel().getLaneChangeCompletion() * result.distanceTo(other);
738  if (getLaneChangeModel().isLaneChangeMidpointPassed()) {
739  return PositionVector::positionAtOffset(other, result, dist);
740  }
741  return PositionVector::positionAtOffset(result, other, dist);
742  }
743  return result;
744 }
745 
746 
747 const MSEdge*
749  // too close to the next junction, so avoid an emergency brake here
750  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
752  return *(myCurrEdge + 1);
753  }
754 #ifdef HAVE_INTERNAL_LANES
755  if (myLane != 0) {
756  return myLane->getInternalFollower();
757  }
758 #endif
759  return *myCurrEdge;
760 }
761 
762 void
764  myAngle = angle;
765 }
766 
767 
768 SUMOReal
770  Position p1;
771  Position p2;
772  if (isParking()) {
774  }
776  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
778  } else {
779  p1 = getPosition();
780  }
781  if (myState.myPos >= myType->getLength()) {
782  // vehicle is fully on the new lane
784  } else {
785  p2 = myFurtherLanes.size() > 0
786  ? myFurtherLanes.back()->geometryPositionAtOffset(myFurtherLanes.back()->getPartialOccupatorEnd())
787  : myLane->getShape().front();
788  if (getLaneChangeModel().isChangingLanes() && myFurtherLanes.size() > 0 && getLaneChangeModel().getShadowLane(myFurtherLanes.back()) == 0) {
789  // special case where the target lane has no predecessor
790  p2 = myLane->getShape().front();
791  }
792  }
793  SUMOReal result = (p1 != p2 ? p2.angleTo2D(p1) :
797  result += getLaneChangeModel().getLaneChangeDirection() * DEG2RAD(angleOffset);
798  }
799  return result;
800 }
801 
802 
803 // ------------
804 bool
805 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset) {
806  Stop stop;
807  stop.lane = MSLane::dictionary(stopPar.lane);
809  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
810  return false;
811  }
812  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
814  stop.startPos = stopPar.startPos;
815  stop.endPos = stopPar.endPos;
816  stop.duration = stopPar.duration;
817  stop.until = stopPar.until;
818  stop.timeToBoardNextPerson = 0;
819  stop.timeToLoadNextContainer = 0;
820  stop.awaitedPersons = stopPar.awaitedPersons;
821  stop.awaitedContainers = stopPar.awaitedContainers;
822  if (stop.until != -1) {
823  stop.until += untilOffset;
824  }
825  stop.triggered = stopPar.triggered;
826  stop.containerTriggered = stopPar.containerTriggered;
827  stop.parking = stopPar.parking;
828  stop.reached = false;
829  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
830  if (stop.busstop != 0) {
831  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
832  } else {
833  errorMsg = "Stop";
834  }
835  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
836  return false;
837  }
838  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
839  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
840  }
841  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
842  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
843  }
844  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
845  MSRouteIterator prevStopEdge = myCurrEdge;
846  SUMOReal prevStopPos = myState.myPos;
847  // where to insert the stop
848  std::list<Stop>::iterator iter = myStops.begin();
849  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
850  if (myStops.size() > 0) {
851  prevStopEdge = myStops.back().edge;
852  prevStopPos = myStops.back().endPos;
853  iter = myStops.end();
854  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
855  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
856  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
857  }
858  }
859  } else {
860  if (stopPar.index == STOP_INDEX_FIT) {
861  while (iter != myStops.end() && (iter->edge < stop.edge ||
862  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
863  prevStopEdge = iter->edge;
864  prevStopPos = iter->endPos;
865  ++iter;
866  }
867  } else {
868  int index = stopPar.index;
869  while (index > 0) {
870  prevStopEdge = iter->edge;
871  prevStopPos = iter->endPos;
872  ++iter;
873  --index;
874  }
875  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
876  }
877  }
878  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
879  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
880  if (stop.busstop != 0) {
881  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
882  } else {
883  errorMsg = "Stop";
884  }
885  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
886  return false;
887  }
888  // David.C:
889  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
890  if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) {
891  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
892  return false;
893  }
894  if (!hasDeparted() && myCurrEdge == stop.edge) {
895  SUMOReal pos = -1;
897  pos = myParameter->departPos;
898  if (pos < 0.) {
899  pos += (*myCurrEdge)->getLength();
900  }
901  }
903  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
904  }
905  if (pos > stop.endPos) {
906  if (stop.busstop != 0) {
907  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
908  } else {
909  errorMsg = "Stop";
910  }
911  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
912  return false;
913  }
914  }
915  if (iter != myStops.begin()) {
916  std::list<Stop>::iterator iter2 = iter;
917  iter2--;
918  if (stop.until >= 0 && iter2->until > stop.until) {
919  if (stop.busstop != 0) {
920  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
921  } else {
922  errorMsg = "Stop";
923  }
924  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
925  }
926  }
927  myStops.insert(iter, stop);
928  return true;
929 }
930 
931 
932 bool
934  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
935 }
936 
937 
938 bool
940  return isStopped() && myStops.begin()->parking;
941 }
942 
943 
944 bool
946  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
947 }
948 
949 
950 bool
952  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
953 }
954 
955 
956 SUMOReal
958  if (myStops.empty()) {
959  // no stops; pass
960  return currentVelocity;
961  }
962  Stop& stop = myStops.front();
963  if (stop.reached) {
964  // ok, we have already reached the next stop
965  // any waiting persons may board now
966  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
967  boarded &= stop.awaitedPersons.size() == 0;
968  // load containers
969  bool loaded = MSNet::getInstance()->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
970  loaded &= stop.awaitedContainers.size() == 0;
971  if (boarded) {
972  if (stop.busstop != 0) {
973  const std::vector<MSTransportable*>& persons = myPersonDevice->getTransportables();
974  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
975  stop.busstop->removeTransportable(*i);
976  }
977  }
978  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
979  stop.triggered = false;
983  }
984  }
985  if (loaded) {
986  if (stop.containerstop != 0) {
987  const std::vector<MSTransportable*>& containers = myContainerDevice->getTransportables();
988  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
990  }
991  }
992  // the triggering condition has been fulfilled
993  stop.containerTriggered = false;
997  }
998  }
999  if (stop.duration <= 0 && !stop.triggered && !stop.containerTriggered) {
1001  } else {
1002  // we have to wait some more time
1004  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1007  }
1009  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1012  }
1013  stop.duration -= DELTA_T;
1014  return 0;
1015  }
1016  } else {
1017  // is the next stop on the current lane?
1018  if (stop.edge == myCurrEdge) {
1019  // get the stopping position
1020  SUMOReal endPos = stop.endPos;
1021  bool busStopsMustHaveSpace = true;
1022  if (stop.busstop != 0) {
1023  // on bus stops, we have to wait for free place if they are in use...
1024  endPos = stop.busstop->getLastFreePos(*this);
1025  // at least half the bus has to fit on non-empty bus stops
1026  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
1027  busStopsMustHaveSpace = false;
1028  }
1029  }
1030  bool containerStopsMustHaveSpace = true;
1031  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
1032  if (stop.containerstop != 0) {
1033  // on container stops, we have to wait for free place if they are in use...
1034  endPos = stop.containerstop->getLastFreePos(*this);
1035  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
1036  containerStopsMustHaveSpace = false;
1037  }
1038  }
1039  // we use the same offset for container stops as for bus stops. we might have to change it at some point!
1040  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace
1041  && containerStopsMustHaveSpace && myLane == stop.lane) {
1042  // ok, we may stop (have reached the stop)
1043  stop.reached = true;
1044  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
1046  // compute stopping time
1047  if (stop.until >= 0) {
1048  if (stop.duration == -1) {
1050  } else {
1052  }
1053  }
1054  if (stop.busstop != 0) {
1055  // let the bus stop know the vehicle
1056  stop.busstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
1057  }
1058  if (stop.containerstop != 0) {
1059  // let the container stop know the vehicle
1061  }
1062  }
1063  // decelerate
1064  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos());
1065  }
1066  }
1067  return currentVelocity;
1068 }
1069 
1070 
1071 const ConstMSEdgeVector
1073  ConstMSEdgeVector result;
1074  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1075  result.push_back(*iter->edge);
1076  }
1077  return result;
1078 }
1079 
1080 
1081 void
1082 MSVehicle::planMove(const SUMOTime t, const MSVehicle* pred, const SUMOReal lengthsInFront) {
1083  planMoveInternal(t, pred, myLFLinkLanes);
1084  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
1086 }
1087 
1088 
1089 void
1090 MSVehicle::planMoveInternal(const SUMOTime t, const MSVehicle* pred, DriveItemVector& lfLinks) const {
1091 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1092  if (gDebugSelectedVehicle == getID()) {
1093  int bla = 0;
1094  }
1095 #endif
1096  // remove information about approaching links, will be reset later in this step
1097  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
1098  if ((*i).myLink != 0) {
1099  (*i).myLink->removeApproaching(this);
1100  }
1101  }
1102  lfLinks.clear();
1103  //
1104  const MSCFModel& cfModel = getCarFollowModel();
1105  const SUMOReal vehicleLength = getVehicleType().getLength();
1106  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
1107  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
1108  // vBeg is the initial maximum velocity of this vehicle in this step
1109  SUMOReal v = MIN2(maxV, laneMaxV);
1110 #ifndef NO_TRACI
1111  if (myInfluencer != 0) {
1112  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1113  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
1114  }
1115 #endif
1116 
1117  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1118  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
1119  assert(bestLaneConts.size() > 0);
1120 #ifdef HAVE_INTERNAL_LANES
1121  bool hadNonInternal = false;
1122 #else
1123  bool hadNonInternal = true;
1124 #endif
1125  SUMOReal seen = myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
1126  SUMOReal seenNonInternal = 0;
1127  SUMOReal vLinkPass = MIN2(estimateSpeedAfterDistance(seen, v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1128  unsigned int view = 0;
1129  DriveProcessItem* lastLink = 0;
1130  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
1131  SUMOReal gap = 0;
1132  if (pred != 0) {
1133  if (pred == myLane->getPartialOccupator()) {
1135  } else {
1137  }
1138  }
1139  std::pair<const MSVehicle*, SUMOReal> leaderInfo = std::make_pair(pred, gap);
1140  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1141  const MSLane* lane = myLane;
1142  while (true) {
1143  // check leader on lane
1144  // leader is given for the first edge only
1145  adaptToLeader(leaderInfo, seen, lastLink, lane, v, vLinkPass);
1146  if (getLaneChangeModel().hasShadowVehicle()) {
1147  // also slow down for leaders on the shadowLane
1148  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1149  if (shadowLane != 0) {
1150  std::pair<const MSVehicle*, SUMOReal> shadowLeaderInfo = shadowLane->getLeader(this, lane->getLength() - seen, false);
1151  adaptToLeader(shadowLeaderInfo, seen, lastLink, shadowLane, v, vLinkPass);
1152  }
1153  }
1154 
1155  // process stops
1156  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
1157  // we are approaching a stop on the edge; must not drive further
1158  const Stop& stop = *myStops.begin();
1159  const SUMOReal endPos = stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this);
1160  const SUMOReal stopDist = seen + endPos - lane->getLength();
1161  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), stopDist);
1162  if (lastLink != 0) {
1163  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1164  }
1165  v = MIN2(v, stopSpeed);
1166  lfLinks.push_back(DriveProcessItem(v, stopDist));
1167  break;
1168  }
1169 
1170  // move to next lane
1171  // get the next link used
1172  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1173  // check whether the vehicle is on its final edge
1174  if (myCurrEdge + view + 1 == myRoute->end()) {
1176  myParameter->arrivalSpeed : laneMaxV);
1177  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1178  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1179  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
1180  v = MIN2(v, va);
1181  if (lastLink != 0) {
1182  lastLink->adaptLeaveSpeed(va);
1183  }
1184  lfLinks.push_back(DriveProcessItem(v, seen));
1185  break;
1186  }
1187  // check whether the lane is a dead end
1188  if (lane->isLinkEnd(link)) {
1189  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1190  if (lastLink != 0) {
1191  lastLink->adaptLeaveSpeed(va);
1192  }
1193  v = MIN2(va, v);
1194  lfLinks.push_back(DriveProcessItem(v, seen));
1195  break;
1196  }
1197  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
1198  (*link)->getState() == LINKSTATE_TL_REDYELLOW ||
1199  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
1200  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1201  // We distinguish 3 cases when determining the point at which a vehicle stops:
1202  // - links that require stopping: here the vehicle needs to stop close to the stop line
1203  // to ensure it gets onto the junction in the next step. Othwise the vehicle would 'forget'
1204  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1205  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1206  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1207  // to minimize the time window for passing the junction. If the
1208  // vehicle 'decides' to accelerate and cannot enter the junction in
1209  // the next step, new foes may appear and cause a collision (see #1096)
1210  // - major links: stopping point is irrelevant
1211  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1212  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
1213  // check whether we need to slow down in order to finish a continuous lane change
1214  if (getLaneChangeModel().isChangingLanes()) {
1215  if ( // slow down to finish lane change before a turn lane
1216  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1217  // slow down to finish lane change before the shadow lane ends
1219  (*link)->getViaLaneOrLane()->getParallelLane(-getLaneChangeModel().getLaneChangeDirection()) == 0)) {
1220  // XXX maybe this is too harsh. Vehicles could cut some corners here
1221  const SUMOReal timeRemaining = STEPS2TIME((1 - getLaneChangeModel().getLaneChangeCompletion()) * MSGlobals::gLaneChangeDuration);
1222  const SUMOReal va = MAX2((SUMOReal)0, (seen - POSITION_EPS) / timeRemaining);
1223  v = MIN2(va, v);
1224  }
1225  }
1226 
1227  // - always issue a request to leave the intersection we are currently on
1228  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == 0;
1229  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
1230  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == 0;
1231  // - even if red, if we cannot break we should issue a request
1232  bool setRequest = (v > 0 && !abortRequestAfterMinor) || (leavingCurrentIntersection);
1233 
1234  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1235  const SUMOReal brakeDist = cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime();
1236  if (yellowOrRed && seen >= brakeDist) {
1237  // the vehicle is able to brake in front of a yellow/red traffic light
1238  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1239  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1240  break;
1241  }
1242 
1243 #ifdef HAVE_INTERNAL_LANES
1245  // we want to pass the link but need to check for foes on internal lanes
1246  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
1247  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1248  // the vehicle to enter the junction first has priority
1249  const MSVehicle* leader = (*it).vehAndGap.first;
1250  if (leader == 0) {
1251  // leader is a pedestrian. Passing 'this' as a dummy.
1252  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
1253  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1254  } else if ((*link)->isLeader(this, leader)) {
1255  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1256  if (lastLink != 0) {
1257  // we are not yet on the junction with this linkLeader.
1258  // at least we can drive up to the previous link and stop there
1259  v = MAX2(v, lastLink->myVLinkWait);
1260  }
1261  // if blocked by a leader from the same lane we must yield our request
1262  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
1263  setRequest = false;
1264  }
1265  }
1266  }
1267  // if this is the link between two internal lanes we may have to slow down for pedestrians
1268  vLinkWait = MIN2(vLinkWait, v);
1269  }
1270 #endif
1271 
1272  if (lastLink != 0) {
1273  lastLink->adaptLeaveSpeed(laneMaxV);
1274  }
1275  SUMOReal arrivalSpeed = vLinkPass;
1276  // vehicles should decelerate when approaching a minor link
1277  // - unless they are close enough to have clear visibility and may start to accelerate again
1278  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1279  if (!(*link)->havePriority() && stopDist > cfModel.getMaxDecel() && brakeDist < seen) {
1280  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1281  arrivalSpeed = MIN2(vLinkPass, cfModel.getMaxDecel() + cfModel.getMaxAccel());
1282  slowedDownForMinor = true;
1283  }
1284  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1285  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1286  const SUMOReal accel = (arrivalSpeed >= v) ? cfModel.getMaxAccel() : -cfModel.getMaxDecel();
1287  const SUMOReal accelTime = (arrivalSpeed - v) / accel;
1288  const SUMOReal accelWay = accelTime * (arrivalSpeed + v) * 0.5;
1289  const SUMOReal nonAccelWay = MAX2(SUMOReal(0), seen - accelWay);
1290  // will either drive as fast as possible and decelerate as late as possible
1291  // or accelerate as fast as possible and then hold that speed
1292  const SUMOReal nonAccelSpeed = MAX3(v, arrivalSpeed, SUMO_const_haltingSpeed);
1293  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1294  const SUMOTime arrivalTime = t - DELTA_T + TIME2STEPS(accelTime + nonAccelWay / nonAccelSpeed);
1295 
1296  // compute speed, time if vehicle starts braking now
1297  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1298  SUMOReal arrivalSpeedBraking = 0;
1299  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1300  if (seen < cfModel.brakeGap(v)) {
1301  // vehicle cannot come to a complete stop in time
1302  // Because we use a continuous formula for computiing the possible slow-down
1303  // we need to handle the mismatch with the discrete dynamics
1304  if (seen < v) {
1305  arrivalSpeedBraking = arrivalSpeed; // no time left for braking after this step
1306  } else if (2 * (seen - v * cfModel.getHeadwayTime()) * -cfModel.getMaxDecel() + v * v >= 0) {
1307  arrivalSpeedBraking = estimateSpeedAfterDistance(seen - v * cfModel.getHeadwayTime(), v, -cfModel.getMaxDecel());
1308  } else {
1309  arrivalSpeedBraking = cfModel.getMaxDecel();
1310  }
1311  // due to discrecte/continuous mismatch we have to ensure that braking actually helps
1312  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1313  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1314  }
1315  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1316  arrivalTime, arrivalSpeed,
1317  arrivalTimeBraking, arrivalSpeedBraking,
1318  seen,
1319  estimateLeaveSpeed(*link, arrivalSpeed)));
1320 #ifdef HAVE_INTERNAL_LANES
1321  if ((*link)->getViaLane() == 0) {
1322  hadNonInternal = true;
1323  ++view;
1324  }
1325 #else
1326  ++view;
1327 #endif
1328  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1329  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD) {
1330  break;
1331  }
1332  // get the following lane
1333  lane = (*link)->getViaLaneOrLane();
1334  laneMaxV = lane->getVehicleMaxSpeed(this);
1335  // the link was passed
1336  // compute the velocity to use when the link is not blocked by other vehicles
1337  // the vehicle shall be not faster when reaching the next lane than allowed
1338  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1339  v = MIN2(va, v);
1340  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1341  seen += lane->getLength();
1342  leaderInfo = lane->getLastVehicleInformation();
1343  leaderInfo.second = leaderInfo.second + seen - lane->getLength() - getVehicleType().getMinGap();
1344  vLinkPass = MIN2(estimateSpeedAfterDistance(lane->getLength(), v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1345  lastLink = &lfLinks.back();
1346  }
1347 
1348 }
1349 
1350 
1351 void
1352 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1353  const SUMOReal seen, DriveProcessItem* const lastLink,
1354  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1355  SUMOReal distToCrossing) const {
1356  if (leaderInfo.first != 0) {
1357  const SUMOReal vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1358  if (lastLink != 0) {
1359  lastLink->adaptLeaveSpeed(vsafeLeader);
1360  }
1361  v = MIN2(v, vsafeLeader);
1362  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1363  }
1364 }
1365 
1366 
1367 SUMOReal
1368 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1369  const SUMOReal seen, const MSLane* const lane, SUMOReal distToCrossing) const {
1370  assert(leaderInfo.first != 0);
1371  const MSCFModel& cfModel = getCarFollowModel();
1372  SUMOReal vsafeLeader = 0;
1373  if (leaderInfo.second >= 0) {
1374  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1375  } else {
1376  // the leading, in-lapping vehicle is occupying the complete next lane
1377  // stop before entering this lane
1378  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1379  }
1380  if (distToCrossing >= 0) {
1381  // drive up to the crossing point with the current link leader
1382  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1383  }
1384  return vsafeLeader;
1385 }
1386 
1387 
1388 bool
1390 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1391  if (gDebugSelectedVehicle == getID()) {
1392  int bla = 0;
1393  }
1394 #endif
1395  // get safe velocities from DriveProcessItems
1396  SUMOReal vSafe = 0; // maximum safe velocity
1397  SUMOReal vSafeZipper = std::numeric_limits<SUMOReal>::max(); // speed limit due to zipper merging
1398  SUMOReal vSafeMin = 0; // minimum safe velocity
1399  // the distance to a link which should either be crossed this step or in
1400  // front of which we need to stop
1401  SUMOReal vSafeMinDist = 0;
1402  myHaveToWaitOnNextLink = false;
1403 
1404  assert(myLFLinkLanes.size() != 0 || (myInfluencer != 0 && myInfluencer->isVTDControlled()));
1405  DriveItemVector::iterator i;
1406  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1407  MSLink* link = (*i).myLink;
1408  // the vehicle must change the lane on one of the next lanes
1409  if (link != 0 && (*i).mySetRequest) {
1410  const LinkState ls = link->getState();
1411  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1412  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1414  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1415  vSafe = (*i).myVLinkWait;
1416  myHaveToWaitOnNextLink = true;
1417  link->removeApproaching(this);
1418  break;
1419  }
1420  //
1421 #ifdef NO_TRACI
1422  const bool influencerPrio = false;
1423 #else
1424  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1425 #endif
1426  std::vector<const SUMOVehicle*> collectFoes;
1427  const bool opened = yellow || influencerPrio ||
1428  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1431  ls == LINKSTATE_ZIPPER ? &collectFoes : 0);
1432  // vehicles should decelerate when approaching a minor link
1433  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont()) {
1434  if ((*i).myDistance > getCarFollowModel().getMaxDecel()) {
1435  vSafe = (*i).myVLinkWait;
1436  myHaveToWaitOnNextLink = true;
1437  if (ls == LINKSTATE_EQUAL) {
1438  link->removeApproaching(this);
1439  }
1440  break; // could be revalidated
1441  } else {
1442  // past the point of no return. we need to drive fast enough
1443  // to make it across the link. However, minor slowdowns
1444  // should be permissible to follow leading traffic safely
1445  // There is a problem in subsecond simulation: If we cannot
1446  // make it across the minor link in one step, new traffic
1447  // could appear on a major foe link and cause a collision
1448  vSafeMin = MIN2((SUMOReal) DIST2SPEED(myLane->getLength() - getPositionOnLane() + POSITION_EPS), (*i).myVLinkPass);
1449  vSafeMinDist = myLane->getLength() - getPositionOnLane();
1450  }
1451  }
1452  // have waited; may pass if opened...
1453  if (opened) {
1454  vSafe = (*i).myVLinkPass;
1455  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1456  // this vehicle is probably not gonna drive accross the next junction (heuristic)
1457  myHaveToWaitOnNextLink = true;
1458  }
1459  } else if (link->getState() == LINKSTATE_ZIPPER) {
1460  vSafeZipper = MIN2(vSafeZipper,
1461  link->getZipperSpeed(this, (*i).myDistance, (*i).myVLinkPass, (*i).myArrivalTime, &collectFoes));
1462  } else {
1463  vSafe = (*i).myVLinkWait;
1464  myHaveToWaitOnNextLink = true;
1465  if (ls == LINKSTATE_EQUAL) {
1466  link->removeApproaching(this);
1467  }
1468  break;
1469  }
1470  } else {
1471  vSafe = (*i).myVLinkWait;
1472  if (vSafe < getSpeed()) {
1473  myHaveToWaitOnNextLink = true;
1474  }
1475  break;
1476  }
1477  }
1478  if (vSafe + NUMERICAL_EPS < vSafeMin) {
1479  // cannot drive across a link so we need to stop before it
1480  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1481  vSafeMin = 0;
1482  myHaveToWaitOnNextLink = true;
1483  }
1484  // vehicles inside a roundabout should maintain their requests
1485  if (myLane->getEdge().isRoundabout()) {
1486  myHaveToWaitOnNextLink = false;
1487  }
1488  vSafe = MIN2(vSafe, vSafeZipper);
1489 
1490  // XXX braking due to lane-changing is not registered and due to processing stops is not registered
1491  // To avoid casual blinking brake lights at high speeds due to dawdling of the
1492  // leading vehicle, we don't show brake lights when the deceleration could be caused
1493  // by frictional forces and air resistance (i.e. proportional to v^2, coefficient could be adapted further)
1494  SUMOReal pseudoFriction = (0.05 + 0.005 * getSpeed()) * getSpeed();
1495  bool brakelightsOn = vSafe < getSpeed() - ACCEL2SPEED(pseudoFriction);
1496  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
1497  SUMOReal vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1498 
1499  // vNext may be higher than vSafe without implying a bug:
1500  // - when approaching a green light that suddenly switches to yellow
1501  // - when using unregulated junctions
1502  // - when using tau < step-size
1503  // - when using unsafe car following models
1504  // - when using TraCI and some speedMode / laneChangeMode settings
1505  //if (vNext > vSafe + NUMERICAL_EPS) {
1506  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1507  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
1508  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1509  //}
1510  vNext = MAX2(vNext, (SUMOReal) 0.);
1511 #ifndef NO_TRACI
1512  if (myInfluencer != 0) {
1513  if (myInfluencer->isVTDControlled()) {
1514  vNext = myInfluencer->implicitSpeedVTD(this, myState.mySpeed);
1515  }
1517  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1518  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1519  }
1520 #endif
1521  // visit waiting time
1522  if (vNext <= SUMO_const_haltingSpeed) {
1525  brakelightsOn = true;
1526  } else {
1527  myWaitingTime = 0;
1529  }
1530 
1531  if (brakelightsOn) {
1533  } else {
1535  }
1536  // call reminders after vNext is set
1537  const SUMOReal pos = myState.myPos;
1538 
1539  // update position and speed
1541 
1542  SUMOReal deltaPos = SPEED2DIST(vNext);
1543 #ifndef NO_TRACI
1544  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
1545  deltaPos = myInfluencer->implicitDeltaPosVTD(this);
1546  }
1547 #endif
1548  myState.myPos += deltaPos;
1549  myState.mySpeed = vNext;
1551  std::vector<MSLane*> passedLanes;
1552  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1553  passedLanes.push_back(*i);
1554  }
1555  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1556  passedLanes.push_back(myLane);
1557  }
1558  bool moved = false;
1559  std::string emergencyReason = " for unknown reasons";
1560  // move on lane(s)
1561  if (myState.myPos <= myLane->getLength()) {
1562  // we are staying at our lane
1563  // there is no need to go over succeeding lanes
1564  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
1565  } else {
1566  // we are moving at least to the next lane (maybe pass even more than one)
1567  if (myCurrEdge != myRoute->end() - 1) {
1568  MSLane* approachedLane = myLane;
1569  // move the vehicle forward
1570  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1572  MSLink* link = (*i).myLink;
1573  // check whether the vehicle was allowed to enter lane
1574  // otherwise it is decelareted and we do not need to test for it's
1575  // approach on the following lanes when a lane changing is performed
1576  // proceed to the next lane
1577  if (link != 0) {
1578  approachedLane = link->getViaLaneOrLane();
1579 #ifndef NO_TRACI
1581 #endif
1582  if (link->getState() == LINKSTATE_TL_RED) {
1583  emergencyReason = " because of a red traffic light";
1584  break;
1585  }
1586 #ifndef NO_TRACI
1587  }
1588 #endif
1589  } else {
1590  emergencyReason = " because there is no connection to the next edge";
1591  approachedLane = 0;
1592  break;
1593  }
1594  if (approachedLane != myLane && approachedLane != 0) {
1595  myState.myPos -= myLane->getLength();
1596  assert(myState.myPos > 0);
1597  enterLaneAtMove(approachedLane);
1598  myLane = approachedLane;
1599 #ifdef HAVE_INTERNAL_LANES
1601  // erase leaders when past the junction
1602  if (link->getViaLane() == 0) {
1603  link->passedJunction(this);
1604  }
1605  }
1606 #endif
1607  if (hasArrived()) {
1608  break;
1609  }
1610  if (getLaneChangeModel().isChangingLanes()) {
1611  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
1612  // abort lane change
1613  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
1614  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1616  }
1617  }
1618  moved = true;
1619  if (approachedLane->getEdge().isVaporizing()) {
1621  break;
1622  }
1623  }
1624  passedLanes.push_back(approachedLane);
1625  }
1626  }
1627  }
1628  // clear previously set information
1629  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1630  (*i)->resetPartialOccupation(this);
1631  }
1632  myFurtherLanes.clear();
1633 
1634  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
1635  if (myState.myPos > myLane->getLength()) {
1636  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
1637  + "'" + emergencyReason
1638  + " (decel=" + toString(myAcceleration - myState.mySpeed)
1639  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1642  myState.mySpeed = 0;
1643  }
1644  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
1645  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1646  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
1647  while (leftLength > 0 && i != passedLanes.rend()) {
1648  myFurtherLanes.push_back(*i);
1649  leftLength -= (*i)->setPartialOccupation(this, leftLength);
1650  ++i;
1651  }
1652  }
1653  updateBestLanes();
1654  // bestLanes need to be updated before lane changing starts
1655  if (getLaneChangeModel().isChangingLanes()) {
1657  }
1658  setBlinkerInformation(); // needs updated bestLanes
1659  //change the blue light only for emergency vehicles SUMOVehicleClass
1660  if (myType->getVehicleClass() == SVC_EMERGENCY) {
1661  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
1662  }
1663  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1665  myAngle = computeAngle();
1666  }
1667  return moved;
1668 }
1669 
1670 
1671 SUMOReal
1672 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
1673  SUMOReal lengths = 0;
1674  const MSLane::VehCont& vehs = l->getVehiclesSecure();
1675  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1676  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()) {
1677  foundStopped = true;
1678  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
1679  l->releaseVehicles();
1680  return ret;
1681  }
1682  lengths += (*i)->getVehicleType().getLengthWithGap();
1683  }
1684  l->releaseVehicles();
1685  return l->getLength() - lengths;
1686 }
1687 
1688 
1689 void
1690 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
1691 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1692  if (gDebugSelectedVehicle == getID()) {
1693  int bla = 0;
1694  }
1695 #endif
1696 #ifdef HAVE_INTERNAL_LANES
1698  bool hadVehicle = false;
1699  SUMOReal seenSpace = -lengthsInFront;
1700 
1701  bool foundStopped = false;
1702  // compute available space until a stopped vehicle is found
1703  // this is the sum of non-interal lane length minus in-between vehicle lenghts
1704  for (unsigned int i = 0; i < lfLinks.size(); ++i) {
1705  // skip unset links
1706  DriveProcessItem& item = lfLinks[i];
1707  if (item.myLink == 0 || foundStopped) {
1708  item.availableSpace = seenSpace;
1709  item.hadVehicle = hadVehicle;
1710  continue;
1711  }
1712  // get the next lane, determine whether it is an internal lane
1713  const MSLane* approachedLane = item.myLink->getViaLane();
1714  if (approachedLane != 0) {
1715  if (item.myLink->hasFoes() && item.myLink->keepClear()/* && item.myLink->willHaveBlockedFoe()*/) {
1716  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
1717  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1718  } else {
1719  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1720  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1721  }
1722  item.availableSpace = seenSpace;
1723  item.hadVehicle = hadVehicle;
1724  continue;
1725  }
1726  approachedLane = item.myLink->getLane();
1727  const MSVehicle* last = approachedLane->getLastVehicle();
1728  if (last == 0) {
1729  last = approachedLane->getPartialOccupator();
1730  if (last != 0) {
1732  item.availableSpace = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
1733  hadVehicle = true;
1735  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1737  if (last->myHaveToWaitOnNextLink) {
1738  foundStopped = true;
1739  }
1740  } else {
1741  seenSpace += approachedLane->getLength();
1742  item.availableSpace = seenSpace;
1743  }
1744  } else {
1745  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
1746  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
1747  const SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
1748  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
1749  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1750  } else {
1751  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
1752  item.availableSpace = seenSpace;
1753  }
1754  if (last->myHaveToWaitOnNextLink) {
1755  foundStopped = true;
1756  }
1757  hadVehicle = true;
1758  }
1759  item.hadVehicle = hadVehicle;
1760  }
1761 
1762 
1763 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1764  if (gDebugSelectedVehicle == getID()) {
1765  int bla = 0;
1766  }
1767 #endif
1768  // check which links allow continuation and add pass available to the previous item
1769  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
1770  DriveProcessItem& item = lfLinks[i - 1];
1771  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
1772  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
1773 #ifndef NO_TRACI
1775 #endif
1776  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
1779  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
1780  if (!opened && item.myLink != 0) {
1781  if (i > 1) {
1782  DriveProcessItem& item2 = lfLinks[i - 2];
1783  if (item2.myLink != 0 && item2.myLink->isCont()) {
1784  allowsContinuation = true;
1785  }
1786  }
1787  }
1788  if (allowsContinuation) {
1789  item.availableSpace = lfLinks[i].availableSpace;
1790  }
1791  }
1792 
1793  // find removalBegin
1794  int removalBegin = -1;
1795  for (unsigned int i = 0; hadVehicle && i < lfLinks.size() && removalBegin < 0; ++i) {
1796  // skip unset links
1797  const DriveProcessItem& item = lfLinks[i];
1798  if (item.myLink == 0) {
1799  continue;
1800  }
1801  /*
1802  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1803  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1804  removalBegin = lastLinkToInternal;
1805  }
1806  */
1807 
1808  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
1809  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1810  SUMOReal impatienceCorrection = 0;
1811  /*
1812  if(item.myLink->getState()==LINKSTATE_MINOR) {
1813  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1814  }
1815  */
1816  if (leftSpace < -impatienceCorrection / 10. && item.myLink->hasFoes() && item.myLink->keepClear()) {
1817  removalBegin = i;
1818  }
1819  //removalBegin = i;
1820  }
1821  }
1822  // abort requests
1823  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1824  while (removalBegin < (int)(lfLinks.size())) {
1826  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
1827  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1828  lfLinks[removalBegin].mySetRequest = false;
1829  }
1830  ++removalBegin;
1831  }
1832  }
1833  }
1834 #else
1835  UNUSED_PARAMETER(lengthsInFront);
1836 #endif
1837  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
1838  if ((*i).myLink != 0) {
1839  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
1840  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((size_t)2); // tie braker
1841  }
1842  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1843  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
1844  }
1845  }
1846 }
1847 
1848 
1849 void
1851  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1852  // skip the reminder if it is a lane reminder but not for my lane
1853  if (rem->first->getLane() != 0 && rem->second > 0.) {
1854 #ifdef _DEBUG
1855  if (myTraceMoveReminders) {
1856  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
1857  }
1858 #endif
1859  ++rem;
1860  } else {
1861  if (rem->first->notifyEnter(*this, reason)) {
1862 #ifdef _DEBUG
1863  if (myTraceMoveReminders) {
1864  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
1865  }
1866 #endif
1867  ++rem;
1868  } else {
1869 #ifdef _DEBUG
1870  if (myTraceMoveReminders) {
1871  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
1872  }
1873 #endif
1874  rem = myMoveReminders.erase(rem);
1875  }
1876  }
1877  }
1878 }
1879 
1880 
1881 bool
1882 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1883  myAmOnNet = !onTeleporting;
1884  // vaporizing edge?
1885  /*
1886  if (enteredLane->getEdge().isVaporizing()) {
1887  // yep, let's do the vaporization...
1888  myLane = enteredLane;
1889  return true;
1890  }
1891  */
1892  // move mover reminder one lane further
1893  adaptLaneEntering2MoveReminder(*enteredLane);
1894  // set the entered lane as the current lane
1895  myLane = enteredLane;
1896 
1897  // internal edges are not a part of the route...
1898  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1899  ++myCurrEdge;
1900  }
1901  if (!onTeleporting) {
1903  } else {
1905  // normal move() isn't called so reset position here
1906  myState.myPos = 0;
1908  }
1909  return hasArrived();
1910 }
1911 
1912 
1913 void
1915  myAmOnNet = true;
1916  myLane = enteredLane;
1918  // need to update myCurrentLaneInBestLanes
1919  updateBestLanes();
1920  // switch to and activate the new lane's reminders
1921  // keep OldLaneReminders
1922  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1923  addReminder(*rem);
1924  }
1926  MSLane* lane = myLane;
1927  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1928  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
1929  if (lane != 0) {
1930  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
1931  }
1932  if (lane != 0) {
1933  myFurtherLanes[i]->resetPartialOccupation(this);
1934  myFurtherLanes[i] = lane;
1935  leftLength -= (lane)->setPartialOccupation(this, leftLength);
1936  } else {
1937  // keep the old values, but ensure there is no shadow
1940  }
1941  }
1942  }
1943  myAngle = computeAngle();
1944 }
1945 
1946 
1947 void
1949  myState = State(pos, speed);
1950  if (myDeparture == NOT_YET_DEPARTED) {
1951  onDepart();
1952  }
1954  assert(myState.myPos >= 0);
1955  assert(myState.mySpeed >= 0);
1956  myWaitingTime = 0;
1957  myLane = enteredLane;
1958  myAmOnNet = true;
1959  if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
1960  // set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
1961  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1962  addReminder(*rem);
1963  }
1964  activateReminders(notification);
1965  }
1966  // build the list of lanes the vehicle is lapping into
1967  SUMOReal leftLength = myType->getLength() - pos;
1968  MSLane* clane = enteredLane;
1969  while (leftLength > 0) {
1970  clane = clane->getLogicalPredecessorLane();
1971  if (clane == 0 || clane == myLane) {
1972  break;
1973  }
1974  myFurtherLanes.push_back(clane);
1975  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1976  }
1977  myAngle = computeAngle();
1978 }
1979 
1980 
1981 void
1983  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1984  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1985 #ifdef _DEBUG
1986  if (myTraceMoveReminders) {
1987  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
1988  }
1989 #endif
1990  ++rem;
1991  } else {
1992 #ifdef _DEBUG
1993  if (myTraceMoveReminders) {
1994  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
1995  }
1996 #endif
1997  rem = myMoveReminders.erase(rem);
1998  }
1999  }
2001  // @note. In case of lane change, myFurtherLanes and partial occupation
2002  // are handled in enterLaneAtLaneChange()
2003  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
2004  (*i)->resetPartialOccupation(this);
2005  }
2006  myFurtherLanes.clear();
2007  }
2008  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
2009  myAmOnNet = false;
2010  }
2012  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
2013  }
2015  while (!myStops.empty() && myStops.front().edge == myCurrEdge) {
2016  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
2017  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
2018  myStops.pop_front();
2019  }
2020  }
2021 }
2022 
2023 
2026  return *myLaneChangeModel;
2027 }
2028 
2029 
2032  return *myLaneChangeModel;
2033 }
2034 
2035 
2036 const std::vector<MSVehicle::LaneQ>&
2038  return *myBestLanes.begin();
2039 }
2040 
2041 
2042 void
2043 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
2044 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2045  if (gDebugSelectedVehicle == getID()) {
2046  int bla = 0;
2047  myLastBestLanesEdge = 0;
2048  }
2049 #endif
2050  if (startLane == 0) {
2051  startLane = myLane;
2052  }
2053  assert(startLane != 0);
2054  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
2056  return;
2057  }
2058  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
2059  if (myBestLanes.size() == 0 || forceRebuild) {
2060  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
2061  updateBestLanes(true, startLane->getLogicalPredecessorLane());
2062  }
2063  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
2064  return;
2065  }
2066  // adapt best lanes to fit the current internal edge:
2067  // keep the entries that are reachable from this edge
2068  const MSEdge* nextEdge = startLane->getInternalFollower();
2069  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
2070  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
2071  std::vector<LaneQ>& lanes = *it;
2072  assert(lanes.size() > 0);
2073  if (&(lanes[0].lane->getEdge()) == nextEdge) {
2074  // keep those lanes which are successors of internal lanes from the edge of startLane
2075  std::vector<LaneQ> oldLanes = lanes;
2076  lanes.clear();
2077  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
2078  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
2079  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
2080  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
2081  lanes.push_back(*it_lane);
2082  break;
2083  }
2084  }
2085  }
2086  assert(lanes.size() == startLane->getEdge().getLanes().size());
2087  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
2088  for (int i = 0; i < (int)lanes.size(); ++i) {
2089  if (i + lanes[i].bestLaneOffset < 0) {
2090  lanes[i].bestLaneOffset = -i;
2091  }
2092  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
2093  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
2094  }
2095  assert(i + lanes[i].bestLaneOffset >= 0);
2096  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
2097  if (lanes[i].bestContinuations[0] != 0) {
2098  // patch length of bestContinuation to match expectations (only once)
2099  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
2100  }
2101  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
2102  myCurrentLaneInBestLanes = lanes.begin() + i;
2103  }
2104  assert(&(lanes[i].lane->getEdge()) == nextEdge);
2105  }
2106  myLastBestLanesInternalLane = startLane;
2108  return;
2109  } else {
2110  // remove passed edges
2111  it = myBestLanes.erase(it);
2112  }
2113  }
2114  assert(false); // should always find the next edge
2115  }
2116  // start rebuilding
2117  myLastBestLanesEdge = &startLane->getEdge();
2118  myBestLanes.clear();
2119 
2120  // get information about the next stop
2121  const MSEdge* nextStopEdge = 0;
2122  const MSLane* nextStopLane = 0;
2123  SUMOReal nextStopPos = 0;
2124  if (!myStops.empty()) {
2125  const Stop& nextStop = myStops.front();
2126  nextStopLane = nextStop.lane;
2127  nextStopEdge = &nextStopLane->getEdge();
2128  nextStopPos = nextStop.startPos;
2129  }
2130  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
2131  nextStopEdge = *(myRoute->end() - 1);
2132  nextStopLane = nextStopEdge->getLanes()[myArrivalLane];
2133  nextStopPos = myArrivalPos;
2134  }
2135  if (nextStopEdge != 0) {
2136  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
2137  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
2138  nextStopPos = MAX2(POSITION_EPS, MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS)));
2139  }
2140 
2141  // go forward along the next lanes;
2142  int seen = 0;
2143  SUMOReal seenLength = 0;
2144  bool progress = true;
2145  for (MSRouteIterator ce = myCurrEdge; progress;) {
2146  std::vector<LaneQ> currentLanes;
2147  const std::vector<MSLane*>* allowed = 0;
2148  const MSEdge* nextEdge = 0;
2149  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
2150  nextEdge = *(ce + 1);
2151  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
2152  }
2153  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
2154  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
2155  LaneQ q;
2156  MSLane* cl = *i;
2157  q.lane = cl;
2158  q.bestContinuations.push_back(cl);
2159  q.bestLaneOffset = 0;
2160  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
2161  q.currentLength = q.length;
2162  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
2163  q.occupation = 0;
2164  q.nextOccupation = 0;
2165  currentLanes.push_back(q);
2166  }
2167  //
2168  if (nextStopEdge == *ce) {
2169  progress = false;
2170  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
2171  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
2172  (*q).allowsContinuation = false;
2173  (*q).length = nextStopPos;
2174  (*q).currentLength = (*q).length;
2175  }
2176  }
2177  }
2178 
2179  myBestLanes.push_back(currentLanes);
2180  ++seen;
2181  seenLength += currentLanes[0].lane->getLength();
2182  ++ce;
2183  progress &= (seen <= 4 || seenLength < 3000);
2184  progress &= seen <= 8;
2185  progress &= ce != myRoute->end();
2186  /*
2187  if(progress) {
2188  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
2189  }
2190  */
2191  }
2192 
2193  // we are examining the last lane explicitly
2194  if (myBestLanes.size() != 0) {
2195  SUMOReal bestLength = -1;
2196  int bestThisIndex = 0;
2197  int index = 0;
2198  std::vector<LaneQ>& last = myBestLanes.back();
2199  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2200  if ((*j).length > bestLength) {
2201  bestLength = (*j).length;
2202  bestThisIndex = index;
2203  }
2204  }
2205  index = 0;
2206  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2207  if ((*j).length < bestLength) {
2208  (*j).bestLaneOffset = bestThisIndex - index;
2209  }
2210  }
2211  }
2212  // go backward through the lanes
2213  // track back best lane and compute the best prior lane(s)
2214  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
2215  std::vector<LaneQ>& nextLanes = (*(i - 1));
2216  std::vector<LaneQ>& clanes = (*i);
2217  MSEdge& cE = clanes[0].lane->getEdge();
2218  int index = 0;
2219  SUMOReal bestConnectedLength = -1;
2220  SUMOReal bestLength = -1;
2221  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
2222  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
2223  bestConnectedLength = (*j).length;
2224  }
2225  if (bestLength < (*j).length) {
2226  bestLength = (*j).length;
2227  }
2228  }
2229  // compute index of the best lane (highest length and least offset from the best next lane)
2230  int bestThisIndex = 0;
2231  if (bestConnectedLength > 0) {
2232  index = 0;
2233  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2234  LaneQ bestConnectedNext;
2235  bestConnectedNext.length = -1;
2236  if ((*j).allowsContinuation) {
2237  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
2238  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2239  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
2240  bestConnectedNext = *m;
2241  }
2242  }
2243  }
2244  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
2245  (*j).length += bestLength;
2246  } else {
2247  (*j).length += bestConnectedNext.length;
2248  }
2249  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
2250  }
2251  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
2252  if (clanes[bestThisIndex].length < (*j).length
2253  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))
2254  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) == abs((*j).bestLaneOffset) &&
2255  nextLinkPriority(clanes[bestThisIndex].bestContinuations) < nextLinkPriority((*j).bestContinuations))
2256  ) {
2257  bestThisIndex = index;
2258  }
2259  }
2260 
2261  } else {
2262  // only needed in case of disconnected routes
2263  int bestNextIndex = 0;
2264  int bestDistToNeeded = (int) clanes.size();
2265  index = 0;
2266  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2267  if ((*j).allowsContinuation) {
2268  int nextIndex = 0;
2269  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
2270  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2271  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
2272  bestDistToNeeded = abs((*m).bestLaneOffset);
2273  bestThisIndex = index;
2274  bestNextIndex = nextIndex;
2275  }
2276  }
2277  }
2278  }
2279  }
2280  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
2281  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
2282 
2283  }
2284  // set bestLaneOffset for all lanes
2285  index = 0;
2286  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2287  if ((*j).length < clanes[bestThisIndex].length
2288  || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))
2289  || (nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)
2290  ) {
2291  (*j).bestLaneOffset = bestThisIndex - index;
2292  if ((nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)) {
2293  // try to move away from the lower-priority lane before it ends
2294  (*j).length = (*j).currentLength;
2295  }
2296  } else {
2297  (*j).bestLaneOffset = 0;
2298  }
2299  }
2300  }
2302  return;
2303 }
2304 
2305 
2306 int
2307 MSVehicle::nextLinkPriority(const std::vector<MSLane*>& conts) {
2308  if (conts.size() < 2) {
2309  return -1;
2310  } else {
2311  MSLink* link = MSLinkContHelper::getConnectingLink(*conts[0], *conts[1]);
2312  if (link != 0) {
2313  return link->havePriority() ? 1 : 0;
2314  } else {
2315  // disconnected route
2316  return -1;
2317  }
2318  }
2319 }
2320 
2321 
2322 void
2324  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
2325  std::vector<LaneQ>::iterator i;
2326  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
2327  SUMOReal nextOccupation = 0;
2328  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
2329  nextOccupation += (*j)->getBruttoVehLenSum();
2330  }
2331  (*i).nextOccupation = nextOccupation;
2332  if ((*i).lane == startLane) {
2334  }
2335  }
2336 }
2337 
2338 
2339 const std::vector<MSLane*>&
2341  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2342  return myEmptyLaneVector;
2343  }
2344  return (*myCurrentLaneInBestLanes).bestContinuations;
2345 }
2346 
2347 
2348 const std::vector<MSLane*>&
2350  const MSLane* lane = l;
2352  // internal edges are not kept inside the bestLanes structure
2353  lane = lane->getLinkCont()[0]->getLane();
2354  }
2355  if (myBestLanes.size() == 0) {
2356  return myEmptyLaneVector;
2357  }
2358  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
2359  if ((*i).lane == lane) {
2360  return (*i).bestContinuations;
2361  }
2362  }
2363  return myEmptyLaneVector;
2364 }
2365 
2366 
2367 int
2369  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2370  return 0;
2371  } else {
2372  return (*myCurrentLaneInBestLanes).bestLaneOffset;
2373  }
2374 }
2375 
2376 
2377 void
2379  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
2380  assert(laneIndex < (int)preb.size());
2381  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
2382 }
2383 
2384 
2385 bool
2387  if (getPositionOnLane() > myLane->getLength()) {
2390  return true;
2391  }
2392  return false;
2393 }
2394 
2395 
2396 SUMOReal
2397 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) const {
2399  if (isOnRoad() && destEdge != NULL) {
2400  if (&myLane->getEdge() == *myCurrEdge) {
2401  // vehicle is on a normal edge
2402  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
2403  } else {
2404  // vehicle is on inner junction edge
2405  distance = myLane->getLength() - getPositionOnLane();
2406  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
2407  }
2408  }
2409  return distance;
2410 }
2411 
2412 
2413 std::pair<const MSVehicle* const, SUMOReal>
2415  if (myLane == 0) {
2416  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
2417  }
2418  if (dist == 0) {
2420  }
2421  const MSVehicle* lead = 0;
2422  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
2423  assert(vehs.size() > 0);
2424  MSLane::VehCont::const_iterator it = std::find(vehs.begin(), vehs.end(), this);
2425  if (it != vehs.end() && it + 1 != vehs.end()) {
2426  lead = *(it + 1);
2427  }
2428  if (lead != 0) {
2429  std::pair<const MSVehicle* const, SUMOReal> result(lead,
2432  return result;
2433  }
2435  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
2436  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
2437  return myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
2438 }
2439 
2440 
2441 SUMOReal
2443  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader();
2444  if (leaderInfo.first == 0 || getSpeed() == 0) {
2445  return -1;
2446  }
2447  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
2448 }
2449 
2450 
2451 SUMOReal
2454 }
2455 
2456 
2457 SUMOReal
2460 }
2461 
2462 
2463 SUMOReal
2466 }
2467 
2468 
2469 SUMOReal
2472 }
2473 
2474 
2475 SUMOReal
2478 }
2479 
2480 
2481 SUMOReal
2484 }
2485 
2486 
2487 SUMOReal
2490 }
2491 
2492 
2493 SUMOReal
2496 }
2497 
2498 
2499 void
2501  if (myPersonDevice == 0) {
2503  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
2504  }
2506  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
2507  unsigned int numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2508  if (numExpected != 0) {
2509  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
2510  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
2511  // Bus drivers usually do not know the names of the passengers.
2512  myStops.front().awaitedPersons.erase(person->getID());
2513  numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2514  }
2515  if (numExpected == 0) {
2516  myStops.front().duration = 0;
2517  }
2518  }
2519 }
2520 
2521 void
2523  if (myContainerDevice == 0) {
2525  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
2526  }
2527  myContainerDevice->addTransportable(container);
2528  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
2529  unsigned int numExpected = (unsigned int) myStops.front().awaitedContainers.size();
2530  if (numExpected != 0) {
2531  myStops.front().awaitedContainers.erase(container->getID());
2532  numExpected = (unsigned int) myStops.front().awaitedContainers.size();
2533  }
2534  if (numExpected == 0) {
2535  myStops.front().duration = 0;
2536  }
2537  }
2538 }
2539 
2540 
2541 const std::vector<MSTransportable*>&
2543  if (myPersonDevice == 0) {
2545  } else {
2547  }
2548 }
2549 
2550 
2551 const std::vector<MSTransportable*>&
2553  if (myContainerDevice == 0) {
2555  } else {
2557  }
2558 }
2559 
2560 
2561 unsigned int
2563  unsigned int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
2564  return boarded + myParameter->personNumber;
2565 }
2566 
2567 unsigned int
2569  unsigned int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
2570  return loaded + myParameter->containerNumber;
2571 }
2572 
2573 
2574 void
2577  int state = getLaneChangeModel().getOwnState();
2578  if ((state & LCA_LEFT) != 0) {
2580  } else if ((state & LCA_RIGHT) != 0) {
2582  } else if (getLaneChangeModel().isChangingLanes()) {
2583  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
2585  } else {
2587  }
2588  } else {
2589  const MSLane* lane = getLane();
2590  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
2591  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
2592  switch ((*link)->getDirection()) {
2593  case LINKDIR_TURN:
2594  case LINKDIR_LEFT:
2595  case LINKDIR_PARTLEFT:
2597  break;
2598  case LINKDIR_RIGHT:
2599  case LINKDIR_PARTRIGHT:
2601  break;
2602  default:
2603  break;
2604  }
2605  }
2606  }
2607 
2608 }
2609 
2610 void
2612  if (currentTime % 1000 == 0) {
2615  } else {
2617  }
2618  }
2619 }
2620 
2621 
2622 void
2624  if (myType->amVehicleSpecific()) {
2625  delete myType;
2626  }
2627  myType = type;
2628 }
2629 
2630 unsigned int
2632  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
2633  return (unsigned int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
2634 }
2635 
2636 
2637 void
2639  assert(lane != 0);
2640  myLane = lane;
2641  myState.myPos = pos;
2642 }
2643 
2644 
2645 bool
2647  // the following links are unsafe:
2648  // - zipper links if they are close enough and have approaching vehicles in the relevant time range
2649  // - unprioritized links if the vehicle is currently approaching a prioritzed link and unable to stop in time
2651  const SUMOReal dist = getCarFollowModel().brakeGap(getSpeed(), getCarFollowModel().getMaxDecel(), 0);
2652  if (seen < dist) {
2653  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(lane);
2654  unsigned int view = 1;
2655  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
2656  DriveItemVector::const_iterator di = myLFLinkLanes.begin();
2657  while (!lane->isLinkEnd(link) && seen <= dist) {
2658  if (!lane->getEdge().isInternal()
2659  && (((*link)->getState() == LINKSTATE_ZIPPER && seen < MSLink::ZIPPER_ADAPT_DIST)
2660  || !(*link)->havePriority())) {
2661  // find the drive item corresponding to this link
2662  bool found = false;
2663  while (di != myLFLinkLanes.end() && !found) {
2664  if ((*di).myLink != 0) {
2665  const MSLane* diPredLane = (*di).myLink->getApproachingLane();
2666  if (diPredLane != 0) {
2667  if (&diPredLane->getEdge() == &lane->getEdge()) {
2668  found = true;
2669  }
2670  }
2671  }
2672  if (!found) {
2673  di++;
2674  }
2675  }
2676  if (found) {
2677  const SUMOTime leaveTime = (*link)->getLeaveTime((*di).myArrivalTime, (*di).myArrivalSpeed,
2678  (*di).getLeaveSpeed(), getVehicleType().getLength());
2679  if ((*link)->hasApproachingFoe((*di).myArrivalTime, leaveTime, (*di).myArrivalSpeed, getCarFollowModel().getMaxDecel())) {
2680  //std::cout << SIMTIME << " veh=" << getID() << " aborting changeTo=" << Named::getIDSecure(bestLaneConts.front()) << " linkState=" << toString((*link)->getState()) << " seen=" << seen << " dist=" << dist << "\n";
2681  return true;
2682  }
2683  }
2684  // no drive item is found if the vehicle aborts it's request within dist
2685  }
2686  lane = (*link)->getViaLaneOrLane();
2687  if (!lane->getEdge().isInternal()) {
2688  view++;
2689  }
2690  seen += lane->getLength();
2691  link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
2692  }
2693  }
2694  return false;
2695 }
2696 
2697 
2698 #ifndef NO_TRACI
2699 bool
2700 MSVehicle::addTraciStop(MSLane* const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until,
2701  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
2702  //if the stop exists update the duration
2703  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2704  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
2705  if (duration == 0 && !iter->reached) {
2706  myStops.erase(iter);
2707  } else {
2708  iter->duration = duration;
2709  }
2710  return true;
2711  }
2712  }
2713 
2715  newStop.lane = lane->getID();
2716  newStop.startPos = startPos;
2717  newStop.endPos = endPos;
2718  newStop.duration = duration;
2719  newStop.until = until;
2720  newStop.triggered = triggered;
2721  newStop.containerTriggered = containerTriggered;
2722  newStop.parking = parking;
2723  newStop.index = STOP_INDEX_FIT;
2724  const bool result = addStop(newStop, errorMsg);
2725  if (myLane != 0) {
2726  updateBestLanes(true);
2727  }
2728  return result;
2729 }
2730 
2731 
2732 bool
2733 MSVehicle::addTraciBusOrContainerStop(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
2734  const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string& errorMsg) {
2735  //if the stop exists update the duration
2736  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2737  const Named* const stop = isContainerStop ? (Named*)iter->containerstop : iter->busstop;
2738  if (stop != 0 && stop->getID() == stopId) {
2739  if (duration == 0 && !iter->reached) {
2740  myStops.erase(iter);
2741  } else {
2742  iter->duration = duration;
2743  }
2744  return true;
2745  }
2746  }
2747 
2749  MSStoppingPlace* bs = 0;
2750  if (isContainerStop) {
2751  newStop.containerstop = stopId;
2752  bs = MSNet::getInstance()->getContainerStop(stopId);
2753  if (bs == 0) {
2754  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
2755  return false;
2756  }
2757  } else {
2758  newStop.busstop = stopId;
2759  bs = MSNet::getInstance()->getBusStop(stopId);
2760  if (bs == 0) {
2761  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
2762  return false;
2763  }
2764  }
2765  newStop.duration = duration;
2766  newStop.until = until;
2767  newStop.triggered = triggered;
2768  newStop.containerTriggered = containerTriggered;
2769  newStop.parking = parking;
2770  newStop.index = STOP_INDEX_FIT;
2771  newStop.lane = bs->getLane().getID();
2772  newStop.endPos = bs->getEndLanePosition();
2773  newStop.startPos = bs->getBeginLanePosition();
2774  const bool result = addStop(newStop, errorMsg);
2775  if (myLane != 0) {
2776  updateBestLanes(true);
2777  }
2778  return result;
2779 }
2780 
2781 
2782 bool
2784  if (isStopped()) {
2788  }
2792  }
2793  // we have waited long enough and fulfilled any passenger-requirements
2794  if (myStops.front().busstop != 0) {
2795  // inform bus stop about leaving it
2796  myStops.front().busstop->leaveFrom(this);
2797  }
2798  // we have waited long enough and fulfilled any container-requirements
2799  if (myStops.front().containerstop != 0) {
2800  // inform container stop about leaving it
2801  myStops.front().containerstop->leaveFrom(this);
2802  }
2803  // the current stop is no longer valid
2805  myStops.pop_front();
2806  // do not count the stopping time towards gridlock time.
2807  // Other outputs use an independent counter and are not affected.
2808  myWaitingTime = 0;
2809  // maybe the next stop is on the same edge; let's rebuild best lanes
2810  updateBestLanes(true);
2811  // continue as wished...
2813  return true;
2814  }
2815  return false;
2816 }
2817 
2818 
2821  return myStops.front();
2822 }
2823 
2824 
2827  if (myInfluencer == 0) {
2828  myInfluencer = new Influencer();
2829  }
2830  return *myInfluencer;
2831 }
2832 
2833 
2834 SUMOReal
2836  if (myInfluencer != 0) {
2837  return myInfluencer->getOriginalSpeed();
2838  }
2839  return myState.mySpeed;
2840 }
2841 
2842 
2843 int
2845  if (hasInfluencer()) {
2847  MSNet::getInstance()->getCurrentTimeStep(),
2848  myLane->getEdge(),
2849  getLaneIndex(),
2850  state);
2851  }
2852  return state;
2853 }
2854 #endif
2855 
2856 
2857 void
2860  // here starts the vehicle internal part (see loading)
2861  std::vector<SUMOTime> internals;
2862  internals.push_back(myDeparture);
2863  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
2864  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
2867  out.closeTag();
2868 }
2869 
2870 
2871 void
2872 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
2873  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
2874  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
2875  }
2876  unsigned int routeOffset;
2877  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
2878  bis >> myDeparture;
2879  bis >> routeOffset;
2880  if (hasDeparted()) {
2881  myDeparture -= offset;
2882  myCurrEdge += routeOffset;
2883  }
2886  // no need to reset myCachedPosition here since state loading happens directly after creation
2887 }
2888 
2889 /****************************************************************************/
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:521
void resetRoutePosition(unsigned int index)
Definition: MSVehicle.cpp:632
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:938
void setAngle(SUMOReal angle)
Set a custom vehicle angle in rad.
Definition: MSVehicle.cpp:763
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1281
The link is a partial left direction.
#define DIST2SPEED(x)
Definition: SUMOTime.h:57
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
const MSVehicleType * myType
This Vehicle&#39;s type.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:2623
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:285
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Adds a vehicle to the list of waiting vehiclse to a given edge.
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:1882
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:467
static int nextLinkPriority(const std::vector< MSLane * > &conts)
get a numerical value for the priority of the upcoming link
Definition: MSVehicle.cpp:2307
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:864
SUMOReal getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
long long int SUMOTime
Definition: SUMOTime.h:43
bool amVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
SUMOReal speed() const
Speed of this state.
Definition: MSVehicle.h:111
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:679
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
SUMOReal rotationAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
void remove(MSVehicle *veh)
Remove a vehicle from this transfer object.
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:49
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:1425
MoveReminderCont myMoveReminders
Current lane&#39;s move reminder.
SUMOReal myArrivalPos
The position on the destination lane where the vehicle stops.
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
const MSEdge * myLastBestLanesEdge
Definition: MSVehicle.h:1280
std::string containerstop
(Optional) container stop if one is assigned to the stop
LaneChangeMode
modes for resolving conflicts between external control (traci) and vehicle control over lane changing...
Definition: MSVehicle.h:894
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1278
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1307
LaneChangeMode myRightDriveLC
changing to the rightmost lane
Definition: MSVehicle.h:1185
const MSEdge * getInternalFollower() const
Returns the lane&#39;s follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:761
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1283
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:302
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:627
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1301
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1273
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:2820
A lane area vehicles can halt at.
const Position geometryPositionAtOffset(SUMOReal offset) const
Definition: MSLane.h:339
SUMOReal getMaxSpeed() const
Returns the maximum speed.
DriveItemVector myLFLinkLanes
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1377
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.cpp:128
bool resumeFromStopping()
Definition: MSVehicle.cpp:2783
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1310
bool hasInfluencer() const
Definition: MSVehicle.h:1200
SUMOTime duration
The stopping duration.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:185
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
The action is done to help someone else.
SUMOTime myLastVTDAccess
Definition: MSVehicle.h:1174
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:553
SUMOReal getImpatience() const
Returns this vehicles impatience.
void setBlinkerInformation()
Definition: MSVehicle.cpp:2575
#define M_PI
Definition: angles.h:37
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:2522
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1369
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
Definition: MSVehicle.cpp:2646
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1298
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2835
The vehicle arrived at a junction.
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:394
bool isVTDControlled() const
Definition: MSVehicle.cpp:427
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:413
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle&#39;s follow speed (no dawdling)
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:375
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:718
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:89
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:565
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:59
bool myConsiderMaxAcceleration
Whether the maximum acceleration shall be regarded.
Definition: MSVehicle.h:1158
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:133
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
SUMOReal getLength() const
Get vehicle&#39;s length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:974
SUMOReal currentLength
The length which may be driven on this lane.
Definition: MSVehicle.h:547
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1292
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:572
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:1012
SUMOReal implicitDeltaPosVTD(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new VTD position ...
Definition: MSVehicle.cpp:466
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2464
bool myRespectJunctionPriority
Whether the junction priority rules are respected.
Definition: MSVehicle.h:1164
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:673
void registerEmergencyStop()
register emergency stop
SUMOReal getEndLanePosition() const
Returns the end position of this stop.
State & operator=(const State &state)
Assignment operator.
Definition: MSVehicle.cpp:113
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:160
T MAX2(T a, T b)
Definition: StdDefs.h:75
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:85
vehicle doesn&#39;t want to change
Definition: MSVehicle.h:184
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2562
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:902
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
const MSRoute * myRoute
This Vehicle&#39;s route.
const std::string & getID() const
returns the id of the transportable
unsigned int myNumberReroutes
The number of reroutings.
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
void postProcessVTD(MSVehicle *v)
Definition: MSVehicle.cpp:438
SUMOReal estimateLeaveSpeed(const MSLink *const link, const SUMOReal vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:1383
SUMOTime until
The time at which the vehicle may continue its journey.
WaitingTimeCollector myWaitingTimeCollector
Definition: MSVehicle.h:1270
SUMOReal mySpeed
the stored speed
Definition: MSVehicle.h:120
const int STOP_INDEX_FIT
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:647
This is an uncontrolled, right-before-left link.
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:2452
void removeWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Removes a vehicle from the list of waiting vehicles to a given edge.
unsigned int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons) ...
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1389
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
SUMOTime myMemorySize
the maximal memory to store
Definition: MSVehicle.h:167
std::pair< const MSVehicle *const, SUMOReal > getLeader(SUMOReal dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2414
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:221
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:340
int myArrivalLane
The destination lane where the vehicle stops.
const SUMOVehicleParameter * myParameter
This Vehicle&#39;s parameter.
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:358
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:52
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1315
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:957
The action is due to a TraCI request.
A storage for edge travel times and efforts.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
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:545
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.cpp:1425
The action is urgent (to be defined by lc-model)
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:63
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
T MAX3(T a, T b, T c)
Definition: StdDefs.h:89
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
int influenceChangeDecision(const SUMOTime currentTime, const MSEdge &currentEdge, const unsigned int currentLaneIndex, int state)
Applies stored LaneChangeMode information and laneTimeLine.
Definition: MSVehicle.cpp:286
#define abs(a)
Definition: polyfonts.c:67
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:1914
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, unsigned int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:898
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:667
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
WaitingTimeCollector(SUMOTime memory=MSGlobals::gWaitingTimeMemory)
Constructor.
Definition: MSVehicle.cpp:142
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2025
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1428
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:295
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:93
The lane is given.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
Right blinker lights are switched on.
Definition: MSVehicle.h:860
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle&#39;s end.
Definition: MSLane.h:260
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:551
SUMOReal getElectricityConsumption() const
Returns electricity consumption of the current state.
Definition: MSVehicle.cpp:2488
The vehicles starts to stop.
Definition: MSNet.h:544
void unregisterOneWaitingForContainer()
decreases the count of vehicles waiting for a container to allow recogniztion of container related de...
SUMOTime getMemorySize() const
Definition: MSVehicle.h:156
SUMOReal slopeDegreeAtOffset(SUMOReal pos) const
Returns the slope at the given length.
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
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:1948
WaitingTimeCollector & operator=(const WaitingTimeCollector &wt)
Assignment operator.
Definition: MSVehicle.cpp:147
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:253
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:121
static std::vector< MSTransportable * > myEmptyTransportableVector
Definition: MSVehicle.h:1286
const std::string & getID() const
Returns the id.
Definition: Named.h:65
A road/street connecting two junctions.
Definition: MSEdge.h:80
The vehicle changes lanes (micro only)
Wants go to the left.
MSLane * lane
The described lane.
Definition: MSVehicle.h:543
void checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:1690
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:562
Left blinker lights are switched on.
Definition: MSVehicle.h:862
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1308
#define max(a, b)
Definition: polyfonts.c:65
void setEmergencyBrakeRedLight(bool value)
Sets whether red lights shall be a reason to brake.
Definition: MSVehicle.cpp:400
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time.
Definition: MSCFModel.h:234
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
const MSLane & getLane() const
Returns the lane this stop is located at.
unsigned int getContainerNumber() const
Returns the number of containers.
Definition: MSVehicle.cpp:2568
SUMOReal computeAngle() const
compute the current vehicle angle
Definition: MSVehicle.cpp:769
void setVTDControlled(MSLane *l, SUMOReal pos, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:416
SUMOReal implicitSpeedVTD(const MSVehicle *veh, SUMOReal oldSpeed)
return the speed that is implicit in the new VTD position
Definition: MSVehicle.cpp:456
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:576
SUMOReal startPos
The stopping position start.
The edge is a district edge.
Definition: MSEdge.h:99
std::pair< MSVehicle *const, SUMOReal > getLeaderOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh, const std::vector< MSLane * > &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:1166
The vehicle got a new route.
Definition: MSNet.h:538
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:663
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:780
vehicle want&#39;s to change to right lane
Definition: MSVehicle.h:188
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:91
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:655
Stores the waiting intervals over the previous seconds (memory is to be specified in ms...
Definition: MSVehicle.h:128
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Encapsulated SAX-Attributes.
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:285
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, unsigned int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:247
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:182
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:2340
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
TraciLaneChangePriority myTraciLaneChangePriority
flags for determining the priority of traci lane change requests
Definition: MSVehicle.h:1188
SUMOReal endPos
The stopping position end.
bool loadAnyWaiting(MSEdge *edge, MSVehicle *vehicle, MSVehicle::Stop *stop)
load any applicable containers Loads any container that is waiting on that edge for the given vehicle...
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:620
SUMOReal myAngle
the angle (
Definition: MSVehicle.h:1318
virtual MSContainerControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:698
A list of positions.
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:2043
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:617
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:681
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
Position myCachedPosition
Definition: MSVehicle.h:1320
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:308
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:651
static SUMOReal gap(SUMOReal predPos, SUMOReal predLength, SUMOReal pos)
Uses the given values to compute the brutto-gap.
Definition: MSVehicle.h:269
SUMOReal myOriginalSpeed
The velocity before influence.
Definition: MSVehicle.h:1149
bool triggered
whether an arriving person lets the vehicle continue
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0)
Adds a stop.
Definition: MSVehicle.cpp:805
std::list< Stop > myStops
The vehicle&#39;s list of stops.
Definition: MSVehicle.h:1289
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
const int STOP_INDEX_END
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:110
const std::vector< MSTransportable * > & getTransportables() const
Returns the list of transportables using this vehicle.
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:933
bool isStoppedInRange(SUMOReal pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:951
std::pair< MSVehicle *, SUMOReal > getLastVehicleInformation() const
Returns the last vehicle which is still on the lane.
Definition: MSLane.cpp:563
bool myConsiderMaxDeceleration
Whether the maximum deceleration shall be regarded.
Definition: MSVehicle.h:1161
SUMOReal getLastFreePos(const SUMOVehicle &forVehicle) const
Returns the last free position on this stop.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
void adaptLeaveSpeed(const SUMOReal v)
Definition: MSVehicle.h:1362
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1276
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:1091
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition) ...
Definition: MSVehicle.h:1313
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
Influencer * myInfluencer
An instance of a velocity/lane influencing instance; built in "getInfluencer".
Definition: MSVehicle.h:1432
const std::vector< MSTransportable * > & getContainers() const
retrieve riding containers
Definition: MSVehicle.cpp:2552
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1284
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:2397
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:128
SUMOReal getSafeFollowSpeed(const std::pair< const MSVehicle *, SUMOReal > leaderInfo, const SUMOReal seen, const MSLane *const lane, SUMOReal distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:1368
Position positionAtOffset(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
SUMOReal getSpaceTillLastStanding(const MSLane *l, bool &foundStopped) const
Definition: MSVehicle.cpp:1672
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:663
bool isRoundabout() const
Definition: MSEdge.h:609
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:395
T MIN2(T a, T b)
Definition: StdDefs.h:69
The link is a (hard) right direction.
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap2pred) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
#define POSITION_EPS
Definition: config.h:187
The brake lights are on.
Definition: MSVehicle.h:866
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSVehicle.h:1397
void addTransportable(MSTransportable *transportable)
Add a passenger.
A blue emergency light is on.
Definition: MSVehicle.h:882
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:541
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:2872
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:551
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: MSVehicle.h:677
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:69
std::pair< MSVehicle *const, SUMOReal > getLeader(const MSVehicle *veh, const SUMOReal vehPos, bool checkNext) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:1135
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:186
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:368
MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:880
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuouss lane change.
#define DEG2RAD(x)
Definition: GeomHelper.h:45
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1269
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:54
LaneChangeMode mySpeedGainLC
lane changing to travel with higher speed
Definition: MSVehicle.h:1183
virtual SUMOReal freeSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal seen, SUMOReal maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:95
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:88
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:247
The link is a partial right direction.
virtual SUMOReal getHeadwayTime() const
Get the driver&#39;s reaction time [s].
Definition: MSCFModel.h:205
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:103
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:939
LaneChangeMode myCooperativeLC
lane changing with the intent to help other vehicles
Definition: MSVehicle.h:1181
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2037
SUMOReal getLaneChangeCompletion() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
bool containerTriggered
whether an arriving container lets the vehicle continue
Wants go to the right.
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:555
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:2494
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
Definition: MSVehicle.cpp:2542
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:89
void unregisterOneWaitingForPerson()
decreases the count of vehicles waiting for a person to allow recogniztion of person related deadlock...
Base class for objects which have an id.
Definition: Named.h:45
void registerOneWaitingForPerson()
increases the count of vehicles waiting for a person to allow recogniztion of person related deadlock...
void saveState(OutputDevice &out)
Saves the states of a vehicle.
Definition: MSVehicle.cpp:2858
void planMoveInternal(const SUMOTime t, const MSVehicle *pred, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:1090
SUMOReal getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.h:1119
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:2470
std::string lane
The lane to stop at.
bool myEmergencyBrakeRedLight
Whether red lights are a reason to brake.
Definition: MSVehicle.h:1167
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:653
Influencer()
Constructor.
Definition: MSVehicle.cpp:220
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
ConstMSEdgeVector myVTDRoute
Definition: MSVehicle.h:1173
void enter(SUMOVehicle *what, SUMOReal beg, SUMOReal end)
Called if a vehicle enters this stop.
void leaveLane(const MSMoveReminder::Notification reason)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:1982
SUMOReal getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:178
unsigned int getVehicleNumber() const
Returns the number of vehicles on this lane.
Definition: MSLane.h:284
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:2476
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2458
void updateOccupancyAndCurrentBestLane(const MSLane *startLane)
updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
Definition: MSVehicle.cpp:2323
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:2611
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:772
void registerOneWaitingForContainer()
increases the count of vehicles waiting for a container to allow recogniztion of container related de...
vehicle want&#39;s to change to left lane
Definition: MSVehicle.h:186
The action is needed to follow the route (navigational lc)
The vehicle starts or ends parking.
~Influencer()
Destructor.
Definition: MSVehicle.cpp:236
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:240
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:242
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2826
#define BUS_STOP_OFFSET
Definition: MSVehicle.cpp:86
static MSDevice_Transportable * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into, const bool isContainer)
Build devices for the given vehicle, if needed.
void setTentativeLaneAndPosition(MSLane *lane, const SUMOReal pos)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:2638
Structure representing possible vehicle parameter.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:84
bool getEmergencyBrakeRedLight() const
Returns whether red lights shall be a reason to brake.
Definition: MSVehicle.h:1105
static SUMOReal compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
virtual VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting...
Definition: MSCFModel.h:169
std::vector< std::pair< SUMOTime, SUMOReal > > mySpeedTimeLine
The velocity time line to apply.
Definition: MSVehicle.h:1143
SUMOReal getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MSVehicle.cpp:707
void setNoShadowPartialOccupator(MSLane *lane)
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:669
virtual MSPersonControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:690
The link has yellow light, may pass.
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:388
bool fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:2386
void passTime(SUMOTime dt, bool waiting)
Definition: MSVehicle.cpp:182
bool isLaneChangeMidpointPassed() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
SUMOReal occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:549
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1304
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:557
SUMOReal interpolateLanePosToGeometryPos(SUMOReal lanePos) const
Definition: MSLane.h:333
Definition of vehicle stop (position and duration)
SUMOReal getBeginLanePosition() const
Returns the begin position of this stop.
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:221
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:675
void onDepart()
Called when the vehicle is inserted into the network.
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2482
void adaptToLeader(const std::pair< const MSVehicle *, SUMOReal > leaderInfo, const SUMOReal seen, DriveProcessItem *const lastLink, const MSLane *const lane, SUMOReal &v, SUMOReal &vLinkPass, SUMOReal distToCrossing=-1) const
Definition: MSVehicle.cpp:1352
The action is due to the default of keeping right "Rechtsfahrgebot".
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:93
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:665
void setConsiderSafeVelocity(bool value)
Sets whether the safe velocity shall be regarded.
Definition: MSVehicle.cpp:376
MSStoppingPlace * getContainerStop(const std::string &id) const
Returns the named container stop.
Definition: MSNet.cpp:804
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:1072
int index
at which position in the stops list
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:649
const waitingIntervalList & getWaitingIntervals() const
Definition: MSVehicle.h:161
bool addTraciBusOrContainerStop(const std::string &stopId, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string &errorMsg)
Definition: MSVehicle.cpp:2733
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
The arrival lane is given.
Needs to stay on the current lane.
const std::string & getID() const
Returns the name of the vehicle type.
The vehicle ends to stop.
Definition: MSNet.h:546
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:348
void resetMoved()
reset the flag whether a vehicle already moved to false
SUMOReal departPos
(optional) The position the vehicle shall depart from
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to)
Informs all added listeners about a vehicle&#39;s state change.
Definition: MSNet.cpp:764
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:406
SUMOReal myPos
the stored position
Definition: MSVehicle.h:113
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:945
waitingIntervalList myWaitingIntervals
Definition: MSVehicle.h:172
std::vector< DriveProcessItem > DriveItemVector
Definition: MSVehicle.h:1374
std::vector< std::pair< SUMOTime, unsigned int > > myLaneTimeLine
The lane usage time line to apply.
Definition: MSVehicle.h:1146
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:1082
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:322
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:661
void move2side(SUMOReal amount)
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:748
vehicle want&#39;s to keep the current lane
Definition: MSVehicle.h:190
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Definition: MSLane.h:252
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:213
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:921
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:913
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:2500
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1285
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:2378
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:160
SUMOTime cumulatedWaitingTime(SUMOTime memory=-1) const
Definition: MSVehicle.cpp:161
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:481
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:947
unsigned int size() const
Return the number of passengers / containers.
No information given; use default.
The link has yellow light, has to brake anyway.
unsigned int containerNumber
The static number of containers in the vehicle when it departs.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:109
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:353
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:393
bool mySpeedAdaptationStarted
Whether influencing the speed has already started.
Definition: MSVehicle.h:1152
SUMOEmissionClass getEmissionClass() const
Get this vehicle type&#39;s emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:385
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:2844
void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
Definition: MSVehicle.cpp:1850
The edge is an internal edge.
Definition: MSEdge.h:97
public emergency vehicles
SUMOReal getTimeGap() const
Returns the time gap in seconds to the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2442
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:81
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane&#39;s move reminders.
Definition: MSLane.h:151
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
bool addTraciStop(MSLane *const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, std::string &errorMsg)
Definition: MSVehicle.cpp:2700
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:659
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:653
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:641
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:687
Back-at-zero position.
LaneChangeMode myStrategicLC
lane changing which is necessary to follow the current route
Definition: MSVehicle.h:1179
The link has red light (must brake) but indicates upcoming green.
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:433
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:626
Interface for lane-change models.
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:2368
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Definition: Position.h:243
bool myConsiderSafeVelocity
Whether the safe velocity shall be regarded.
Definition: MSVehicle.h:1155
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:382
SUMOTime myDeparture
The real departure time.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
static const SUMOTime NOT_YET_DEPARTED
MSDevice_Transportable * myContainerDevice
The containers this vehicle may have.
Definition: MSVehicle.h:1295
bool boardAnyWaiting(MSEdge *edge, MSVehicle *vehicle, MSVehicle::Stop *stop)
board any applicable persons Boards any people who wait on that edge for the given vehicle and remove...
std::string id
The vehicle&#39;s id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:671
static const Position INVALID
Definition: Position.h:261
The vehicle is being teleported.
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
const std::string & getID() const
Returns the name of the vehicle.
The action is due to the wish to be faster (tactical lc)
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
unsigned int getLaneIndex() const
Definition: MSVehicle.cpp:2631