SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
18 // Representation of a vehicle in the micro simulation
19 /****************************************************************************/
20 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
21 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
22 /****************************************************************************/
23 //
24 // This file is part of SUMO.
25 // SUMO is free software: you can redistribute it and/or modify
26 // it under the terms of the GNU General Public License as published by
27 // the Free Software Foundation, either version 3 of the License, or
28 // (at your option) any later version.
29 //
30 /****************************************************************************/
31 
32 // ===========================================================================
33 // included modules
34 // ===========================================================================
35 #ifdef _MSC_VER
36 #include <windows_config.h>
37 #else
38 #include <config.h>
39 #endif
40 
41 #include <iostream>
42 #include <cassert>
43 #include <cmath>
44 #include <cstdlib>
45 #include <algorithm>
46 #include <map>
47 #include <utils/common/ToString.h>
54 #include <utils/common/StdDefs.h>
55 #include <utils/geom/GeomHelper.h>
62 #include "MSVehicleControl.h"
63 #include "MSVehicleTransfer.h"
64 #include "MSGlobals.h"
65 #include "MSStoppingPlace.h"
67 #include "MSEdgeWeightsStorage.h"
69 #include "MSMoveReminder.h"
70 #include "MSTransportableControl.h"
71 #include "MSLane.h"
72 #include "MSJunction.h"
73 #include "MSVehicle.h"
74 #include "MSEdge.h"
75 #include "MSVehicleType.h"
76 #include "MSNet.h"
77 #include "MSRoute.h"
78 #include "MSLinkCont.h"
79 #include "MSLeaderInfo.h"
80 
81 #ifdef CHECK_MEMORY_LEAKS
82 #include <foreign/nvwa/debug_new.h>
83 #endif // CHECK_MEMORY_LEAKS
84 
85 // enable here and in utils/gui/globjects/GUIGLObjectPopupMenu.cpp
86 //#define DEBUG_VEHICLE_GUI_SELECTION 1
87 
88 //#define DEBUG_PLAN_MOVE
89 //#define DEBUG_EXEC_MOVE
90 //#define DEBUG_FURTHER
91 //#define DEBUG_STOPS
92 //#define DEBUG_BESTLANES
93 #define DEBUG_COND (getID() == "disabled")
94 
95 #define STOPPING_PLACE_OFFSET 0.5
96 
97 #define CRLL_LOOK_AHEAD 5
98 
99 // @todo Calibrate with real-world values / make configurable
100 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
101 
102 // ===========================================================================
103 // static value definitions
104 // ===========================================================================
105 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
106 std::vector<MSTransportable*> MSVehicle::myEmptyTransportableVector;
107 
108 
109 // ===========================================================================
110 // method definitions
111 // ===========================================================================
112 /* -------------------------------------------------------------------------
113  * methods of MSVehicle::State
114  * ----------------------------------------------------------------------- */
116  myPos = state.myPos;
117  mySpeed = state.mySpeed;
118  myPosLat = state.myPosLat;
119  myBackPos = state.myBackPos;
122 }
123 
124 
127  myPos = state.myPos;
128  mySpeed = state.mySpeed;
129  myPosLat = state.myPosLat;
130  myBackPos = state.myBackPos;
131  myPreviousSpeed = state.myPreviousSpeed;
132  myLastCoveredDist = state.myLastCoveredDist;
133  return *this;
134 }
135 
136 
137 bool
139  return (myPos != state.myPos ||
140  mySpeed != state.mySpeed ||
141  myPosLat != state.myPosLat ||
142  myLastCoveredDist != state.myLastCoveredDist ||
143  myPreviousSpeed != state.myPreviousSpeed ||
144  myBackPos != state.myBackPos);
145 }
146 
147 
149  myPos(pos), mySpeed(speed), myPosLat(posLat), myBackPos(backPos), myPreviousSpeed(speed), myLastCoveredDist(SPEED2DIST(speed)) {}
150 
151 
152 
153 /* -------------------------------------------------------------------------
154  * methods of MSVehicle::WaitingTimeCollector
155  * ----------------------------------------------------------------------- */
156 
158 
159 MSVehicle::WaitingTimeCollector::WaitingTimeCollector(const WaitingTimeCollector& wt) : myMemorySize(wt.getMemorySize()), myWaitingIntervals(wt.getWaitingIntervals()) {}
160 
163  myMemorySize = wt.getMemorySize();
164  myWaitingIntervals = wt.getWaitingIntervals();
165  return *this;
166 }
167 
170  myWaitingIntervals.clear();
171  passTime(t, true);
172  return *this;
173 }
174 
175 SUMOTime
177  assert(memorySpan <= myMemorySize);
178  if (memorySpan == -1) {
179  memorySpan = myMemorySize;
180  }
181  SUMOTime totalWaitingTime = 0;
182  for (waitingIntervalList::const_iterator i = myWaitingIntervals.begin(); i != myWaitingIntervals.end(); i++) {
183  if (i->second >= memorySpan) {
184  if (i->first >= memorySpan) {
185  break;
186  } else {
187  totalWaitingTime += memorySpan - i->first;
188  }
189  } else {
190  totalWaitingTime += i->second - i->first;
191  }
192  }
193  return totalWaitingTime;
194 }
195 
196 void
198  waitingIntervalList::iterator i = myWaitingIntervals.begin();
199  waitingIntervalList::iterator end = myWaitingIntervals.end();
200  bool startNewInterval = i == end || (i->first != 0);
201  while (i != end) {
202  i->first += dt;
203  if (i->first >= myMemorySize) {
204  break;
205  }
206  i->second += dt;
207  i++;
208  }
209 
210  // remove intervals beyond memorySize
211  waitingIntervalList::iterator::difference_type d = std::distance(i, end);
212  while (d > 0) {
213  myWaitingIntervals.pop_back();
214  d--;
215  }
216 
217  if (!waiting) {
218  return;
219  } else if (!startNewInterval) {
220  myWaitingIntervals.begin()->first = 0;
221  } else {
222  myWaitingIntervals.push_front(std::make_pair(0, dt));
223  }
224  return;
225 }
226 
227 
228 
229 
230 
231 /* -------------------------------------------------------------------------
232  * methods of MSVehicle::Influencer
233  * ----------------------------------------------------------------------- */
234 #ifndef NO_TRACI
236  mySpeedAdaptationStarted(true),
237  myConsiderSafeVelocity(true),
238  myConsiderMaxAcceleration(true),
239  myConsiderMaxDeceleration(true),
240  myRespectJunctionPriority(true),
241  myEmergencyBrakeRedLight(true),
242  myLastVTDAccess(-TIME2STEPS(20)),
243  myStrategicLC(LC_NOCONFLICT),
244  myCooperativeLC(LC_NOCONFLICT),
245  mySpeedGainLC(LC_NOCONFLICT),
246  myRightDriveLC(LC_NOCONFLICT),
247  mySublaneLC(LC_NOCONFLICT),
248  myTraciLaneChangePriority(LCP_URGENT) {
249 }
250 
251 
253 
254 
255 void
256 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
257  mySpeedAdaptationStarted = true;
258  mySpeedTimeLine = speedTimeLine;
259 }
260 
261 
262 void
263 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine) {
264  myLaneTimeLine = laneTimeLine;
265 }
266 
267 
268 int
270  return (1 * myConsiderSafeVelocity +
271  2 * myConsiderMaxAcceleration +
272  4 * myConsiderMaxDeceleration +
273  8 * myRespectJunctionPriority +
274  16 * myEmergencyBrakeRedLight);
275 }
276 
277 
278 SUMOReal
280  // keep original speed
281  myOriginalSpeed = speed;
282  // remove leading commands which are no longer valid
283  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
284  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
285  }
286  // do nothing if the time line does not apply for the current time
287  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
288  return speed;
289  }
290  // compute and set new speed
291  if (!mySpeedAdaptationStarted) {
292  mySpeedTimeLine[0].second = speed;
293  mySpeedAdaptationStarted = true;
294  }
295  currentTime += DELTA_T;
296  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
297  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
298  if (myConsiderSafeVelocity) {
299  speed = MIN2(speed, vSafe);
300  }
301  if (myConsiderMaxAcceleration) {
302  speed = MIN2(speed, vMax);
303  }
304  if (myConsiderMaxDeceleration) {
305  speed = MAX2(speed, vMin);
306  }
307  return speed;
308 }
309 
310 
311 int
312 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state) {
313  // remove leading commands which are no longer valid
314  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
315  myLaneTimeLine.erase(myLaneTimeLine.begin());
316  }
317  ChangeRequest changeRequest = REQUEST_NONE;
318  // do nothing if the time line does not apply for the current time
319  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
320  const int destinationLaneIndex = myLaneTimeLine[1].second;
321  if (destinationLaneIndex < (int)currentEdge.getLanes().size()) {
322  if (currentLaneIndex > destinationLaneIndex) {
323  changeRequest = REQUEST_RIGHT;
324  } else if (currentLaneIndex < destinationLaneIndex) {
325  changeRequest = REQUEST_LEFT;
326  } else {
327  changeRequest = REQUEST_HOLD;
328  }
329  }
330  }
331  // check whether the current reason shall be canceled / overridden
332  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
333  // flags for the current reason
334  LaneChangeMode mode = LC_NEVER;
335  if ((state & LCA_STRATEGIC) != 0) {
336  mode = myStrategicLC;
337  } else if ((state & LCA_COOPERATIVE) != 0) {
338  mode = myCooperativeLC;
339  } else if ((state & LCA_SPEEDGAIN) != 0) {
340  mode = mySpeedGainLC;
341  } else if ((state & LCA_KEEPRIGHT) != 0) {
342  mode = myRightDriveLC;
343  } else if ((state & LCA_SUBLANE) != 0) {
344  mode = mySublaneLC;
345  } else if ((state & LCA_TRACI) != 0) {
346  mode = LC_NEVER;
347  } else {
348  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
349  }
350  if (mode == LC_NEVER) {
351  // cancel all lcModel requests
352  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
353  state &= ~LCA_URGENT;
354  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
355  if (
356  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
357  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
358  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
359  // cancel conflicting lcModel request
360  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
361  state &= ~LCA_URGENT;
362  }
363  } else if (mode == LC_ALWAYS) {
364  // ignore any TraCI requests
365  return state;
366  }
367  }
368  // apply traci requests
369  if (changeRequest == REQUEST_NONE) {
370  return state;
371  } else {
372  state |= LCA_TRACI;
373  // security checks
374  if ((myTraciLaneChangePriority == LCP_ALWAYS)
375  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
376  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
377  }
378  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
379  state |= LCA_URGENT;
380  }
381  switch (changeRequest) {
382  case REQUEST_HOLD:
383  return state | LCA_STAY;
384  case REQUEST_LEFT:
385  return state | LCA_LEFT;
386  case REQUEST_RIGHT:
387  return state | LCA_RIGHT;
388  default:
389  throw ProcessError("should not happen");
390  }
391  }
392 }
393 
394 
395 SUMOReal
397  assert(myLaneTimeLine.size() >= 2);
398  assert(currentTime >= myLaneTimeLine[0].first);
399  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
400 }
401 
402 
403 void
405  myConsiderSafeVelocity = value;
406 }
407 
408 
409 void
411  myConsiderMaxAcceleration = value;
412 }
413 
414 
415 void
417  myConsiderMaxDeceleration = value;
418 }
419 
420 
421 void
423  myRespectJunctionPriority = value;
424 }
425 
426 
427 void
429  myEmergencyBrakeRedLight = value;
430 }
431 
432 
433 void
435  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
436  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
437  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
438  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
439  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
440  mySublaneLC = (LaneChangeMode)((value & (1024 + 2048)) >> 10);
441 }
442 
443 
444 void
445 MSVehicle::Influencer::setVTDControlled(Position xyPos, MSLane* l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
446  myVTDXYPos = xyPos;
447  myVTDLane = l;
448  myVTDPos = pos;
449  myVTDPosLat = posLat;
450  myVTDAngle = angle;
451  myVTDEdgeOffset = edgeOffset;
452  myVTDRoute = route;
453  myLastVTDAccess = t;
454 }
455 
456 
457 bool
459  return myLastVTDAccess == MSNet::getInstance()->getCurrentTimeStep();
460 }
461 
462 
463 bool
465  return myLastVTDAccess >= t - TIME2STEPS(10);
466 }
467 
468 void
470  const bool wasOnRoad = v->isOnRoad();
471  if (v->isOnRoad()) {
474  }
475  if (myVTDRoute.size() != 0) {
476  v->replaceRouteEdges(myVTDRoute, true);
477  }
478  v->myCurrEdge = v->getRoute().begin() + myVTDEdgeOffset;
479  if (myVTDLane != 0 && myVTDPos > myVTDLane->getLength()) {
480  myVTDPos = myVTDLane->getLength();
481  }
482  if (myVTDLane != 0 && fabs(myVTDPosLat) < 0.5 * (myVTDLane->getWidth() + v->getVehicleType().getWidth())) {
483  myVTDLane->forceVehicleInsertion(v, myVTDPos, MSMoveReminder::NOTIFICATION_TELEPORT, myVTDPosLat);
484  v->updateBestLanes();
485  if (!wasOnRoad) {
486  v->drawOutsideNetwork(false);
487  }
488  } else {
489  v->setVTDState(myVTDXYPos);
490  v->drawOutsideNetwork(true);
491  }
492  // inverse of GeomHelper::naviDegree
493  v->setAngle(M_PI / 2. - DEG2RAD(myVTDAngle));
494 }
495 
496 
497 SUMOReal
499  SUMOReal dist = 0;
500  if (myVTDLane == 0) {
501  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
502  } else {
503  dist = veh->getDistanceToPosition(myVTDPos, &myVTDLane->getEdge());
504  }
505  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
506  return oldSpeed;
507  } else {
508  return DIST2SPEED(dist);
509  }
510 }
511 
512 SUMOReal
514  SUMOReal dist = 0;
515  if (myVTDLane == 0) {
516  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
517  } else {
518  dist = veh->getDistanceToPosition(myVTDPos, &myVTDLane->getEdge());
519  }
520  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
521  return 0;
522  } else {
523  return dist;
524  }
525 }
526 
527 #endif
528 
529 
530 /* -------------------------------------------------------------------------
531  * MSVehicle-methods
532  * ----------------------------------------------------------------------- */
534  const MSVehicleType* type, const SUMOReal speedFactor) :
535  MSBaseVehicle(pars, route, type, speedFactor),
536  myWaitingTime(0),
538  myState(0, 0, 0, 0), //
539  myLane(0),
542  myPersonDevice(0),
544  myAcceleration(0),
545  mySignals(0),
546  myAmOnNet(false),
549  myHaveToWaitOnNextLink(false),
550  myAngle(0),
551  myStopDist(std::numeric_limits<SUMOReal>::max()),
552  myCachedPosition(Position::INVALID),
553  myEdgeWeights(0)
554 #ifndef NO_TRACI
555  , myInfluencer(0)
556 #endif
557 {
558  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
559  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
560  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
561  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
562  }
563  } else {
564  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
565  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
566  }
567  }
568  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
569  throw ProcessError("Departure speed for vehicle '" + pars->id +
570  "' is too high for the vehicle type '" + type->getID() + "'.");
571  }
572  }
575 }
576 
577 
579  delete myEdgeWeights;
580  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
581  (*i)->resetPartialOccupation(this);
582  }
585  // still needed when calling resetPartialOccupation (getShadowLane) and when removing
586  // approach information from parallel links
587  delete myLaneChangeModel;
588  myFurtherLanes.clear();
589  myFurtherLanesPosLat.clear();
590  //
591  if (myType->amVehicleSpecific()) {
592  delete myType;
593  }
594 #ifndef NO_TRACI
595  delete myInfluencer;
596 #endif
597 }
598 
599 
600 void
604  leaveLane(reason);
605 }
606 
607 
608 // ------------ interaction with the route
609 bool
611  return (myCurrEdge == myRoute->end() - 1
612  && (myStops.empty() || myStops.front().edge != myCurrEdge)
614  && !isRemoteControlled());
615 }
616 
617 
618 bool
619 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset) {
620  const ConstMSEdgeVector& edges = newRoute->getEdges();
621  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
622  if (!onInit && !newRoute->contains(*myCurrEdge)) {
623  return false;
624  }
625 
626  // rebuild in-vehicle route information
627  if (onInit) {
628  myCurrEdge = newRoute->begin();
629  } else {
630  MSRouteIterator newCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);;
631  if (myLane->getEdge().isInternal() && (
632  (newCurrEdge + 1) == edges.end() || (*(newCurrEdge + 1)) != &(myLane->getOutgoingLanes()[0]->getEdge()))) {
633  return false;
634  }
635  myCurrEdge = newCurrEdge;
636  }
637  // check whether the old route may be deleted (is not used by anyone else)
638  newRoute->addReference();
639  myRoute->release();
640  // assign new route
641  myRoute = newRoute;
642  // update arrival definition
644  // update best lanes
647  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
648  // save information that the vehicle was rerouted
651  // recheck old stops
652  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
653  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
654  iter = myStops.erase(iter);
655  } else {
656  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
657  ++iter;
658  }
659  }
660  // add new stops
661  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
662  std::string error;
663  addStop(*i, error);
664  if (error != "") {
665  WRITE_WARNING(error);
666  }
667  }
668  return true;
669 }
670 
671 
672 bool
673 MSVehicle::willPass(const MSEdge* const edge) const {
674  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
675 }
676 
677 
678 int
680  return (int) std::distance(myRoute->begin(), myCurrEdge);
681 }
682 
683 
684 void
686  myCurrEdge = myRoute->begin() + index;
687  // !!! hack
688  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
689 }
690 
691 
692 
695  return _getWeightsStorage();
696 }
697 
698 
701  return _getWeightsStorage();
702 }
703 
704 
707  if (myEdgeWeights == 0) {
709  }
710  return *myEdgeWeights;
711 }
712 
713 
714 // ------------ Interaction with move reminders
715 void
717  // This erasure-idiom works for all stl-sequence-containers
718  // See Meyers: Effective STL, Item 9
719  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
720  // XXX: calling notifyMove with newSpeed seems not the best choice. For the ballistic update, the average speed is calculated and used
721  // although a higher order quadrature-formula might be more adequate.
722  // For the euler case (where the speed is considered constant for each time step) it is conceivable that
723  // the current calculations may lead to systematic errors for large time steps (compared to reality). Refs. #2579
724  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, MAX2((SUMOReal)0., newSpeed))) {
725 #ifdef _DEBUG
726  if (myTraceMoveReminders) {
727  traceMoveReminder("notifyMove", rem->first, rem->second, false);
728  }
729 #endif
730  rem = myMoveReminders.erase(rem);
731  } else {
732 #ifdef _DEBUG
733  if (myTraceMoveReminders) {
734  traceMoveReminder("notifyMove", rem->first, rem->second, true);
735  }
736 #endif
737  ++rem;
738  }
739  }
740 }
741 
742 
743 // XXX: consider renaming...
744 void
746  // save the old work reminders, patching the position information
747  // add the information about the new offset to the old lane reminders
748  const SUMOReal oldLaneLength = myLane->getLength();
749  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
750  rem->second += oldLaneLength;
751 #ifdef _DEBUG
752  if (myTraceMoveReminders) {
753  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
754  }
755 #endif
756  }
757  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
758  addReminder(*rem);
759  }
760 }
761 
762 
763 // ------------ Other getter methods
764 SUMOReal
766  if (myLane == 0) {
767  return 0;
768  }
769  const SUMOReal lp = getPositionOnLane();
771  return myLane->getShape().slopeDegreeAtOffset(gp);
772 }
773 
774 
775 Position
776 MSVehicle::getPosition(const SUMOReal offset) const {
777  if (myLane == 0) {
778  if (isRemoteControlled()) {
779  return myCachedPosition;
780  } else {
781  return Position::INVALID;
782  }
783  }
784  if (isParking()) {
785  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
788  }
789  const bool changingLanes = getLaneChangeModel().isChangingLanes();
790  if (offset == 0. && !changingLanes) {
793  }
794  return myCachedPosition;
795  }
797  return result;
798 }
799 
800 
801 const MSEdge*
803  // too close to the next junction, so avoid an emergency brake here
804  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
806  return *(myCurrEdge + 1);
807  }
808 #ifdef HAVE_INTERNAL_LANES
809  if (myLane != 0) {
810  return myLane->getInternalFollower();
811  }
812 #endif
813  return *myCurrEdge;
814 }
815 
816 void
818  myAngle = angle;
819 }
820 
821 
822 SUMOReal
824  Position p1;
825  const SUMOReal posLat = -myState.myPosLat; // @todo get rid of the '-'
826  if (isParking()) {
828  }
830  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
832  } else {
833  p1 = getPosition();
834  }
835  const Position p2 = getBackPosition();
836  SUMOReal result = (p1 != p2 ? p2.angleTo2D(p1) :
839  result += DEG2RAD(getLaneChangeModel().getAngleOffset());
840  }
841 #ifdef DEBUG_FURTHER
842  if (DEBUG_COND) {
843  std::cout << SIMTIME << " computeAngle veh=" << getID() << " p1=" << p1 << " p2=" << p2 << " angle=" << result << "\n";
844  }
845 #endif
846  return result;
847 }
848 
849 
850 const Position
852  const SUMOReal posLat = -myState.myPosLat; // @todo get rid of the '-'
853  if (myState.myPos >= myType->getLength()) {
854  // vehicle is fully on the new lane
856  } else {
858  // special case where the target lane has no predecessor
859  return myLane->geometryPositionAtOffset(0, posLat);
860  } else {
861 #ifdef DEBUG_FURTHER
862  if (DEBUG_COND) {
863  std::cout << " getBackPosition veh=" << getID() << " myLane=" << myLane->getID() << " further=" << toString(myFurtherLanes) << " myFurtherLanesPosLat=" << toString(myFurtherLanesPosLat) << "\n";
864  }
865 #endif
866  return myFurtherLanes.size() > 0 && !getLaneChangeModel().isChangingLanes()
867  ? myFurtherLanes.back()->geometryPositionAtOffset(getBackPositionOnLane(myFurtherLanes.back()), -myFurtherLanesPosLat.back())
868  : myLane->geometryPositionAtOffset(0, posLat);
869  }
870  }
871 }
872 
873 // ------------
874 bool
875 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset) {
876  Stop stop;
877  stop.lane = MSLane::dictionary(stopPar.lane);
879  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
880  return false;
881  }
882  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
884  stop.startPos = stopPar.startPos;
885  stop.endPos = stopPar.endPos;
886  stop.duration = stopPar.duration;
887  stop.until = stopPar.until;
888  stop.timeToBoardNextPerson = 0;
889  stop.timeToLoadNextContainer = 0;
890  stop.awaitedPersons = stopPar.awaitedPersons;
891  stop.awaitedContainers = stopPar.awaitedContainers;
892  if (stop.until != -1) {
893  stop.until += untilOffset;
894  }
895  stop.triggered = stopPar.triggered;
896  stop.containerTriggered = stopPar.containerTriggered;
897  stop.parking = stopPar.parking;
898  stop.reached = false;
899  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
900  if (stop.busstop != 0) {
901  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
902  } else {
903  errorMsg = "Stop";
904  }
905  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
906  return false;
907  }
908  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
909  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
910  }
911  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
912  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
913  }
914  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
915  MSRouteIterator prevStopEdge = myCurrEdge;
916  SUMOReal prevStopPos = myState.myPos;
917  // where to insert the stop
918  std::list<Stop>::iterator iter = myStops.begin();
919  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
920  if (myStops.size() > 0) {
921  prevStopEdge = myStops.back().edge;
922  prevStopPos = myStops.back().endPos;
923  iter = myStops.end();
924  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
925  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
926  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
927  }
928  }
929  } else {
930  if (stopPar.index == STOP_INDEX_FIT) {
931  while (iter != myStops.end() && (iter->edge < stop.edge ||
932  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
933  prevStopEdge = iter->edge;
934  prevStopPos = iter->endPos;
935  ++iter;
936  }
937  } else {
938  int index = stopPar.index;
939  while (index > 0) {
940  prevStopEdge = iter->edge;
941  prevStopPos = iter->endPos;
942  ++iter;
943  --index;
944  }
945  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
946  }
947  }
948  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
949  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
950  if (stop.busstop != 0) {
951  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
952  } else {
953  errorMsg = "Stop";
954  }
955  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
956  return false;
957  }
958  // David.C:
959  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
960  if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) {
961  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
962  return false;
963  }
964  if (!hasDeparted() && myCurrEdge == stop.edge) {
965  SUMOReal pos = -1;
967  pos = myParameter->departPos;
968  if (pos < 0.) {
969  pos += (*myCurrEdge)->getLength();
970  }
971  }
973  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
974  }
975  if (pos > stop.endPos) {
976  if (stop.busstop != 0) {
977  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
978  } else {
979  errorMsg = "Stop";
980  }
981  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
982  return false;
983  }
984  }
985  if (iter != myStops.begin()) {
986  std::list<Stop>::iterator iter2 = iter;
987  iter2--;
988  if (stop.until >= 0 && iter2->until > stop.until) {
989  if (stop.busstop != 0) {
990  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
991  } else {
992  errorMsg = "Stop";
993  }
994  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
995  }
996  }
997  myStops.insert(iter, stop);
998  return true;
999 }
1000 
1001 
1002 bool
1004  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
1005 }
1006 
1007 
1008 bool
1010  return isStopped() && myStops.begin()->parking;
1011 }
1012 
1013 
1014 bool
1016  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
1017 }
1018 
1019 
1020 bool
1022  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
1023 }
1024 
1025 
1026 SUMOReal
1028  if (myStops.empty()) {
1029  // no stops; pass
1030  return currentVelocity;
1031  }
1032 
1033 #ifdef DEBUG_STOPS
1034  if (DEBUG_COND) {
1035  std::cout << "\nPROCESS_NEXT_STOP\n" << SIMTIME << " vehicle '" << getID() << "'" << std::endl;
1036  }
1037 #endif
1038 
1039  Stop& stop = myStops.front();
1040  if (stop.reached) {
1041 
1042 #ifdef DEBUG_STOPS
1043  if (DEBUG_COND) {
1044  std::cout << SIMTIME << " vehicle '" << getID() << "' reached stop." << std::endl;
1045  }
1046 #endif
1047  // ok, we have already reached the next stop
1048  // any waiting persons may board now
1049  MSNet* const net = MSNet::getInstance();
1050  bool boarded = net->hasPersons() && net->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
1051  boarded &= stop.awaitedPersons.size() == 0;
1052  // load containers
1053  bool loaded = net->hasContainers() && net->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
1054  loaded &= stop.awaitedContainers.size() == 0;
1055  if (boarded) {
1056  if (stop.busstop != 0) {
1057  const std::vector<MSTransportable*>& persons = myPersonDevice->getTransportables();
1058  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
1059  stop.busstop->removeTransportable(*i);
1060  }
1061  }
1062  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
1063  stop.triggered = false;
1067 #ifdef DEBUG_STOPS
1068  if (DEBUG_COND) {
1069  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for person." << std::endl;
1070  }
1071 #endif
1072  }
1073  }
1074  if (loaded) {
1075  if (stop.containerstop != 0) {
1076  const std::vector<MSTransportable*>& containers = myContainerDevice->getTransportables();
1077  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
1079  }
1080  }
1081  // the triggering condition has been fulfilled
1082  stop.containerTriggered = false;
1086 #ifdef DEBUG_STOPS
1087  if (DEBUG_COND) {
1088  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for container." << std::endl;
1089  }
1090 #endif
1091  }
1092  }
1093  if (stop.duration <= 0 && !stop.triggered && !stop.containerTriggered) {
1094 #ifdef DEBUG_STOPS
1095  if (DEBUG_COND) {
1096  std::cout << SIMTIME << " vehicle '" << getID() << "' resumes from stopping." << std::endl;
1097  }
1098 #endif
1100  } else {
1102  if (getVehicleType().getPersonCapacity() == getPersonNumber()) {
1103  WRITE_WARNING("Vehicle '" + getID() + "' ignores triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1104  stop.triggered = false;
1105  }
1106  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1109 #ifdef DEBUG_STOPS
1110  if (DEBUG_COND) {
1111  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for person." << std::endl;
1112  }
1113 #endif
1114  }
1116  if (getVehicleType().getContainerCapacity() == getContainerNumber()) {
1117  WRITE_WARNING("Vehicle '" + getID() + "' ignores container triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1118  stop.containerTriggered = false;
1119  }
1120  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1123 #ifdef DEBUG_STOPS
1124  if (DEBUG_COND) {
1125  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for container." << std::endl;
1126  }
1127 #endif
1128  }
1129  // we have to wait some more time
1130  stop.duration -= DELTA_T;
1131 
1133  // euler
1134  return 0;
1135  } else {
1136  // ballistic:
1137  SUMOReal haltingPos = stop.endPos;
1138  if (stop.busstop != 0) {
1139  haltingPos = stop.busstop->getStoppingPosition(this);
1140  } else if (stop.containerstop != 0) {
1141  haltingPos = stop.containerstop->getStoppingPosition(this);
1142  }
1143  return getCarFollowModel().stopSpeed(this, getSpeed(), haltingPos - myState.pos());
1144  }
1145  }
1146  } else {
1147 
1148 #ifdef DEBUG_STOPS
1149  if (DEBUG_COND) {
1150  std::cout << SIMTIME << " vehicle '" << getID() << "' hasn't reached next stop." << std::endl;
1151  }
1152 #endif
1153 
1154  // is the next stop on the current lane?
1155  if (stop.edge == myCurrEdge) {
1156  // get the stopping position
1157  SUMOReal endPos = stop.endPos;
1158  bool useStoppingPlace = false;
1159  bool fitsOnStoppingPlace = true;
1160  if (stop.busstop != 0) {
1161  useStoppingPlace = true;
1162  // on bus stops, we have to wait for free place if they are in use...
1163  endPos = stop.busstop->getLastFreePos(*this);
1164  // at least half the bus has to fit on non-empty bus stops
1165  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
1166  fitsOnStoppingPlace = false;
1167  }
1168  }
1169  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
1170  if (stop.containerstop != 0) {
1171  useStoppingPlace = true;
1172  // on container stops, we have to wait for free place if they are in use...
1173  endPos = stop.containerstop->getLastFreePos(*this);
1174  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
1175  fitsOnStoppingPlace = false;
1176  }
1177  }
1178  const SUMOReal reachedThreshold = (useStoppingPlace ? endPos - STOPPING_PLACE_OFFSET : stop.startPos) - NUMERICAL_EPS;
1179  if (myState.pos() >= reachedThreshold && fitsOnStoppingPlace && currentVelocity <= SUMO_const_haltingSpeed && myLane == stop.lane) {
1180  // ok, we may stop (have reached the stop)
1181  stop.reached = true;
1182  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
1184  // compute stopping time
1185  if (stop.until >= 0) {
1186  if (stop.duration == -1) {
1188  } else {
1190  }
1191  }
1192  if (stop.busstop != 0) {
1193  // let the bus stop know the vehicle
1194  stop.busstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
1195  }
1196  if (stop.containerstop != 0) {
1197  // let the container stop know the vehicle
1199  }
1200  }
1201  // decelerate
1203  // euler
1204  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos() + NUMERICAL_EPS);
1205  } else {
1206  // ballistic
1207  return getCarFollowModel().stopSpeed(this, myState.mySpeed, endPos - myState.myPos);
1208  }
1209  }
1210  }
1211  return currentVelocity;
1212 }
1213 
1214 
1215 const ConstMSEdgeVector
1217  ConstMSEdgeVector result;
1218  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1219  result.push_back(*iter->edge);
1220  }
1221  return result;
1222 }
1223 
1224 
1225 void
1226 MSVehicle::planMove(const SUMOTime t, const MSLeaderInfo& ahead, const SUMOReal lengthsInFront) {
1227 
1228 #ifdef DEBUG_PLAN_MOVE
1229  if (DEBUG_COND) {
1230  std::cout
1231  << "\nPLAN_MOVE\n"
1232  << STEPS2TIME(t)
1233  << " veh=" << getID()
1234  << " lane=" << myLane->getID()
1235  << " pos=" << getPositionOnLane()
1236  << " posLat=" << getLateralPositionOnLane()
1237  << " speed=" << getSpeed()
1238  << "\n";
1239  }
1240 #endif
1241  planMoveInternal(t, ahead, myLFLinkLanes, myStopDist); // XXX: Why do we reach over myLFLinkLanes and myStopDist as arguments?! That only seems to obscure things (Leo). Refs. #2575
1242 #ifdef DEBUG_PLAN_MOVE
1243  if (DEBUG_COND) {
1244  DriveItemVector::iterator i;
1245  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1246  std::cout
1247  << " vPass=" << (*i).myVLinkPass
1248  << " vWait=" << (*i).myVLinkWait
1249  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1250  << " request=" << (*i).mySetRequest
1251  << "\n";
1252  }
1253  }
1254 #endif
1255  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
1256 #ifdef DEBUG_PLAN_MOVE
1257  if (DEBUG_COND) {
1258  std::cout << " after checkRewindLinkLanes\n";
1259  DriveItemVector::iterator i;
1260  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1261  std::cout
1262  << " vPass=" << (*i).myVLinkPass
1263  << " vWait=" << (*i).myVLinkWait
1264  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1265  << " request=" << (*i).mySetRequest
1266  << " atime=" << (*i).myArrivalTime
1267  << " atimeB=" << (*i).myArrivalTimeBraking
1268  << "\n";
1269  }
1270  }
1271 #endif
1273 }
1274 
1275 
1276 void
1277 MSVehicle::planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector& lfLinks, SUMOReal& myStopDist) const {
1278 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1279  if (gDebugSelectedVehicle == getID()) {
1280  int bla = 0;
1281  }
1282 #endif
1283 
1284  // remove information about approaching links, will be reset later in this step
1286  lfLinks.clear();
1287  myStopDist = std::numeric_limits<SUMOReal>::max();
1288  //
1289  const MSCFModel& cfModel = getCarFollowModel();
1290  const SUMOReal vehicleLength = getVehicleType().getLength();
1291  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
1292  const bool opposite = getLaneChangeModel().isOpposite();
1293  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
1294  // v is the initial maximum velocity of this vehicle in this step
1295  SUMOReal v = MIN2(maxV, laneMaxV);
1296 #ifndef NO_TRACI
1297  if (myInfluencer != 0) {
1298  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1299  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
1300  }
1301 #endif
1302  // all links within dist are taken into account (potentially)
1303  // the distance already "seen"; in the following always up to the end of the current "lane"
1304  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1305 
1306  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
1307 #ifdef DEBUG_PLAN_MOVE
1308  if (DEBUG_COND) {
1309  std::cout << " bestLaneConts=" << toString(bestLaneConts) << "\n";
1310  }
1311 #endif
1312  assert(bestLaneConts.size() > 0);
1313 #ifdef HAVE_INTERNAL_LANES
1314  bool hadNonInternal = false;
1315 #else
1316  bool hadNonInternal = true;
1317 #endif
1318  SUMOReal seen = opposite ? myState.myPos : myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
1319  SUMOReal seenNonInternal = 0;
1320  SUMOReal vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(seen, v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1321  int view = 0;
1322  DriveProcessItem* lastLink = 0;
1323  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
1324  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1325  const MSLane* lane = opposite ? myLane->getOpposite() : myLane;
1326  const MSLane* leaderLane = myLane;
1327  while (true) {
1328  // check leader on lane
1329  // leader is given for the first edge only
1330  adaptToLeaders(ahead, 0, seen, lastLink, leaderLane, v, vLinkPass);
1331 #ifdef DEBUG_PLAN_MOVE
1332  if (DEBUG_COND) {
1333  std::cout << "\nv = " << v << "\n";
1334 
1335  }
1336 #endif
1337  // XXX efficiently adapt to shadow leaders using neighAhead by iteration over the whole edge in parallel (lanechanger-style)
1338  if (getLaneChangeModel().getShadowLane() != 0) {
1339  // also slow down for leaders on the shadowLane relative to the current lane
1340  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1341  if (shadowLane != 0) {
1343  adaptToLeaders(shadowLane->getLastVehicleInformation(this, latOffset, lane->getLength() - seen),
1344  latOffset,
1345  seen, lastLink, shadowLane, v, vLinkPass);
1346  }
1347  }
1348 
1349  // process stops
1350  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge() && !myStops.begin()->reached) {
1351  // we are approaching a stop on the edge; must not drive further
1352  const Stop& stop = *myStops.begin();
1353  const SUMOReal endPos = (stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this)) + NUMERICAL_EPS;
1354  myStopDist = seen + endPos - lane->getLength();
1355  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), myStopDist);
1356  if (lastLink != 0) {
1357  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1358  }
1359  v = MIN2(v, stopSpeed);
1360  lfLinks.push_back(DriveProcessItem(v, myStopDist));
1361 
1362 #ifdef DEBUG_PLAN_MOVE
1363  if (DEBUG_COND) {
1364  std::cout << "\n" << SIMTIME << " next stop: distance = " << myStopDist << " requires stopSpeed = " << stopSpeed << "\n";
1365 
1366  }
1367 #endif
1368 
1369  break;
1370  }
1371 
1372  // move to next lane
1373  // get the next link used
1374  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1375  // check whether the vehicle is on its final edge
1376  if (myCurrEdge + view + 1 == myRoute->end()) {
1378  myParameter->arrivalSpeed : laneMaxV);
1379  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1380  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1381  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
1382  v = MIN2(v, va);
1383  if (lastLink != 0) {
1384  lastLink->adaptLeaveSpeed(va);
1385  }
1386  lfLinks.push_back(DriveProcessItem(v, seen));
1387  break;
1388  }
1389  // check whether the lane or the shadowLane is a dead end
1390  if (lane->isLinkEnd(link) ||
1392  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1393  if (lastLink != 0) {
1394  lastLink->adaptLeaveSpeed(va);
1395  }
1396  v = MIN2(va, v);
1397  lfLinks.push_back(DriveProcessItem(v, seen));
1398  break;
1399  }
1400  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
1401  (*link)->getState() == LINKSTATE_TL_REDYELLOW ||
1402  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
1403  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1404  // We distinguish 3 cases when determining the point at which a vehicle stops:
1405  // - links that require stopping: here the vehicle needs to stop close to the stop line
1406  // to ensure it gets onto the junction in the next step. Otherwise the vehicle would 'forget'
1407  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1408  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1409  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1410  // to minimize the time window for passing the junction. If the
1411  // vehicle 'decides' to accelerate and cannot enter the junction in
1412  // the next step, new foes may appear and cause a collision (see #1096)
1413  // - major links: stopping point is irrelevant
1414  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1415  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
1416  // check whether we need to slow down in order to finish a continuous lane change
1417  if (getLaneChangeModel().isChangingLanes()) {
1418  if ( // slow down to finish lane change before a turn lane
1419  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1420  // slow down to finish lane change before the shadow lane ends
1421  (getLaneChangeModel().getShadowLane() != 0 &&
1422  (*link)->getViaLaneOrLane()->getParallelLane(getLaneChangeModel().getShadowDirection()) == 0)) {
1423  // XXX maybe this is too harsh. Vehicles could cut some corners here
1424  const SUMOReal timeRemaining = STEPS2TIME(getLaneChangeModel().remainingTime());
1425  assert(timeRemaining != 0); // we seem to suppose that isChangingLanes() implies this (Leo)
1426  // XXX: Euler-logic (#860), but I couldn't identify problems from this yet (Leo). Refs. #2575
1427  const SUMOReal va = MAX2((SUMOReal)0, (seen - POSITION_EPS) / timeRemaining);
1428 #ifdef DEBUG_PLAN_MOVE
1429  if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " slowing down to finish continuous change before"
1430  << " link=" << (*link)->getViaLaneOrLane()->getID()
1431  << " timeRemaining=" << timeRemaining
1432  << " v=" << v
1433  << " va=" << va
1434  << "\n";
1435 #endif
1436  v = MIN2(va, v);
1437  }
1438  }
1439 
1440  // - always issue a request to leave the intersection we are currently on
1441  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == 0;
1442  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
1443  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == 0;
1444  // - even if red, if we cannot break we should issue a request
1445  bool setRequest = (v > 0 && !abortRequestAfterMinor) || (leavingCurrentIntersection);
1446 
1447  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1448  const SUMOReal brakeDist = cfModel.brakeGap(myState.mySpeed, cfModel.getMaxDecel(), 0.);
1449  if (yellowOrRed && seen >= brakeDist) {
1450  // the vehicle is able to brake in front of a yellow/red traffic light
1451  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1452  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1453  break;
1454  }
1455 
1456 #ifdef HAVE_INTERNAL_LANES
1458  // we want to pass the link but need to check for foes on internal lanes
1459  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
1460  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1461  // the vehicle to enter the junction first has priority
1462  const MSVehicle* leader = (*it).vehAndGap.first;
1463  if (leader == 0) {
1464  // leader is a pedestrian. Passing 'this' as a dummy.
1465  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
1466  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1467  } else if ((*link)->isLeader(this, leader)) {
1468  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1469  if (lastLink != 0) {
1470  // we are not yet on the junction with this linkLeader.
1471  // at least we can drive up to the previous link and stop there
1472  v = MAX2(v, lastLink->myVLinkWait);
1473  }
1474  // if blocked by a leader from the same lane we must yield our request
1475  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
1476  setRequest = false;
1477  }
1478  }
1479  }
1480  // if this is the link between two internal lanes we may have to slow down for pedestrians
1481  vLinkWait = MIN2(vLinkWait, v);
1482  }
1483 #endif
1484 
1485  if (lastLink != 0) {
1486  lastLink->adaptLeaveSpeed(laneMaxV);
1487  }
1488  SUMOReal arrivalSpeed = vLinkPass;
1489  // vehicles should decelerate when approaching a minor link
1490  // - unless they are close enough to have clear visibility of all relevant foe lanes and may start to accelerate again
1491  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1492 
1493  // whether the vehicle/driver is close enough to the link to see all possible foes #2123
1494  SUMOReal visibilityDistance = (*link)->getFoeVisibilityDistance();
1495  SUMOReal determinedFoePresence = seen < visibilityDistance;
1496 // // VARIANT: account for time needed to recognize whether relevant vehicles are on the foe lanes. (Leo)
1497 // SUMOReal foeRecognitionTime = 0.0;
1498 // SUMOReal determinedFoePresence = seen < visibilityDistance - myState.mySpeed*foeRecognitionTime;
1499 
1500  if (!(*link)->havePriority() && !determinedFoePresence && brakeDist < seen) {
1501  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1502  SUMOReal maxSpeedAtVisibilityDist = cfModel.maximumSafeStopSpeed(visibilityDistance, myState.mySpeed, false, 0.);
1503  // XXX: estimateSpeedAfterDistance does not use euler-logic (thus returns a lower value than possible here...)
1504  SUMOReal maxArrivalSpeed = cfModel.estimateSpeedAfterDistance(visibilityDistance, maxSpeedAtVisibilityDist, cfModel.getMaxAccel());
1505  arrivalSpeed = MIN2(vLinkPass, maxArrivalSpeed);
1506  slowedDownForMinor = true;
1507  }
1508 
1509  SUMOTime arrivalTime;
1511  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1512  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1513  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1514  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, v, arrivalSpeed);
1515  } else {
1516  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, myState.mySpeed, arrivalSpeed);
1517  }
1518 
1519  // compute arrival speed and arrival time if vehicle starts braking now
1520  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1521  SUMOReal arrivalSpeedBraking = 0;
1522  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1523  if (seen < cfModel.brakeGap(v)) { // XXX: should this use the current speed (at least for the ballistic case)? (Leo) Refs. #2575
1524  // vehicle cannot come to a complete stop in time
1526  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeedEuler(seen, v);
1527  // due to discrete/continuous mismatch (when using Euler update) we have to ensure that braking actually helps
1528  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1529  } else {
1530  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeed(seen, myState.mySpeed);
1531  }
1532  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1533  }
1534  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1535  arrivalTime, arrivalSpeed,
1536  arrivalTimeBraking, arrivalSpeedBraking,
1537  seen,
1538  estimateLeaveSpeed(*link, arrivalSpeed)));
1539 #ifdef HAVE_INTERNAL_LANES
1540  if ((*link)->getViaLane() == 0) {
1541  hadNonInternal = true;
1542  ++view;
1543  }
1544 #else
1545  ++view;
1546 #endif
1547  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1548  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD) {
1549  break;
1550  }
1551  // get the following lane
1552  lane = (*link)->getViaLaneOrLane();
1553  laneMaxV = lane->getVehicleMaxSpeed(this);
1554  // the link was passed
1555  // compute the velocity to use when the link is not blocked by other vehicles
1556  // the vehicle shall be not faster when reaching the next lane than allowed
1557  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1558  v = MIN2(va, v);
1559  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1560  // do not restrict results to the current vehicle to allow caching for the current time step
1561  leaderLane = lane; // (opposite && lane->getOpposite() != 0) ? lane->getOpposite() : lane;
1562  // ignore leaders while overtaking through the opposite direction lane
1563  ahead = opposite ? MSLeaderInfo(leaderLane) : leaderLane->getLastVehicleInformation(0, 0);
1564  seen += lane->getLength();
1565  vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(lane->getLength(), v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1566  lastLink = &lfLinks.back();
1567  }
1568 
1569 //#ifdef DEBUG_PLAN_MOVE
1570 // if(DEBUG_COND){
1571 // std::cout << "planMoveInternal found safe speed v = " << v << std::endl;
1572 // }
1573 //#endif
1574 
1575 }
1576 
1577 
1578 void
1580  const SUMOReal seen, DriveProcessItem* const lastLink,
1581  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass) const {
1582  int rightmost;
1583  int leftmost;
1584  ahead.getSubLanes(this, latOffset, rightmost, leftmost);
1585 #ifdef DEBUG_PLAN_MOVE
1586  if (DEBUG_COND) std::cout << SIMTIME
1587  << "\nADAPT_TO_LEADERS\nveh=" << getID()
1588  << " lane=" << lane->getID()
1589  << " rm=" << rightmost
1590  << " lm=" << leftmost
1591  << " ahead=" << ahead.toString()
1592  << "\n";
1593 #endif
1594  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
1595  const MSVehicle* pred = ahead[sublane];
1596  if (pred != 0) {
1597  // @todo avoid multiple adaptations to the same leader
1598  const SUMOReal predBack = pred->getBackPositionOnLane(lane);
1599  const SUMOReal gap = (lastLink == 0
1600  ? predBack - myState.myPos - getVehicleType().getMinGap()
1601  : predBack + seen - lane->getLength() - getVehicleType().getMinGap());
1602 #ifdef DEBUG_PLAN_MOVE
1603  if (DEBUG_COND) {
1604  std::cout << " pred=" << pred->getID() << " predLane=" << pred->getLane()->getID() << " predPos=" << pred->getPositionOnLane() << " gap=" << gap << " predBack=" << predBack << " seen=" << seen << " lane=" << lane->getID() << " myLane=" << myLane->getID() << "\n";
1605  }
1606 #endif
1607  adaptToLeader(std::make_pair(pred, gap), seen, lastLink, lane, v, vLinkPass);
1608  }
1609  }
1610 }
1611 
1612 
1613 void
1614 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1615  const SUMOReal seen, DriveProcessItem* const lastLink,
1616  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1617  SUMOReal distToCrossing) const {
1618  if (leaderInfo.first != 0) {
1619  const SUMOReal vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1620  if (lastLink != 0) {
1621  lastLink->adaptLeaveSpeed(vsafeLeader);
1622  }
1623  v = MIN2(v, vsafeLeader);
1624  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1625 
1626 #ifdef DEBUG_PLAN_MOVE
1627  if (DEBUG_COND) std::cout
1628  << SIMTIME
1629  //std::cout << std::setprecision(10);
1630  << " veh=" << getID()
1631  << " lead=" << leaderInfo.first->getID()
1632  << " leadSpeed=" << leaderInfo.first->getSpeed()
1633  << " gap=" << leaderInfo.second
1634  << " leadLane=" << leaderInfo.first->getLane()->getID()
1635  << " predPos=" << leaderInfo.first->getPositionOnLane()
1636  << " seen=" << seen
1637  << " lane=" << lane->getID()
1638  << " myLane=" << myLane->getID()
1639  << " dTC=" << distToCrossing
1640  << " v=" << v
1641  << " vSafeLeader=" << vsafeLeader
1642  << " vLinkPass=" << vLinkPass
1643  << "\n";
1644 #endif
1645  }
1646 }
1647 
1648 
1649 SUMOReal
1650 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1651  const SUMOReal seen, const MSLane* const lane, SUMOReal distToCrossing) const {
1652  assert(leaderInfo.first != 0);
1653  const MSCFModel& cfModel = getCarFollowModel();
1654  SUMOReal vsafeLeader = 0;
1655  if (leaderInfo.second >= 0) {
1656  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1657  } else {
1658  // the leading, in-lapping vehicle is occupying the complete next lane
1659  // stop before entering this lane
1660  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1661  }
1662  if (distToCrossing >= 0) {
1663  // drive up to the crossing point with the current link leader
1664  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1665  }
1666  return vsafeLeader;
1667 }
1668 
1669 SUMOReal
1671  SUMOReal vNext = myState.mySpeed + ACCEL2SPEED(accel);
1673  // apply implicit Euler positional update
1674  return SPEED2DIST(MAX2(vNext, (SUMOReal)0.));
1675  } else {
1676  // apply ballistic update
1677  if (vNext >= 0) {
1678  // assume constant acceleration during this time step
1679  return SPEED2DIST(myState.mySpeed + 0.5 * ACCEL2SPEED(accel));
1680  } else {
1681  // negative vNext indicates a stop within the middle of time step
1682  // The corresponding stop time is s = mySpeed/deceleration \in [0,dt], and the
1683  // covered distance is therefore deltaPos = mySpeed*s - 0.5*deceleration*s^2.
1684  // Here, deceleration = (myState.mySpeed - vNext)/dt is the constant deceleration
1685  // until the vehicle stops.
1686  return -SPEED2DIST(0.5 * myState.mySpeed * myState.mySpeed / ACCEL2SPEED(accel));
1687  }
1688  }
1689 }
1690 
1691 bool
1693 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1694  if (gDebugSelectedVehicle == getID()) {
1695  int bla = 0;
1696  }
1697 #endif
1698 
1699 #ifdef DEBUG_EXEC_MOVE
1700  if (DEBUG_COND) std::cout << "\nEXECUTE_MOVE\n"
1701  << SIMTIME
1702  << " veh=" << getID()
1703  << " speed=" << getSpeed() // toString(getSpeed(), 24)
1704  << std::endl;
1705 #endif
1706 
1707  // get safe velocities from DriveProcessItems
1708  SUMOReal vSafe = 0; // maximum safe velocity (XXX: why init this as 0 !? Confusing... (Leo)) Refs. #2575
1709  SUMOReal vSafeZipper = std::numeric_limits<SUMOReal>::max(); // speed limit due to zipper merging
1710  SUMOReal vSafeMin = 0; // minimum safe velocity
1711  // the distance to a link which should either be crossed this step or in
1712  // front of which we need to stop
1713  SUMOReal vSafeMinDist = 0;
1714  myHaveToWaitOnNextLink = false;
1715 
1716  assert(myLFLinkLanes.size() != 0 || isRemoteControlled());
1717  DriveItemVector::iterator i;
1718  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1719  MSLink* link = (*i).myLink;
1720 
1721 #ifdef DEBUG_EXEC_MOVE
1722  if (DEBUG_COND) std::cout
1723  << SIMTIME
1724  << " veh=" << getID()
1725  << " link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID())
1726  << " req=" << (*i).mySetRequest
1727  << " vP=" << (*i).myVLinkPass
1728  << " vW=" << (*i).myVLinkWait
1729  << " d=" << (*i).myDistance
1730  << "\n";
1731 #endif
1732 
1733  // the vehicle must change the lane on one of the next lanes (XXX: refs to code further below???, Leo)
1734  if (link != 0 && (*i).mySetRequest) {
1735 
1736  const LinkState ls = link->getState();
1737  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1738  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1739  const SUMOReal brakeGap = getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.);
1740  if (yellow && ((*i).myDistance > brakeGap || (MSGlobals::gSemiImplicitEulerUpdate && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel())))) {
1741  vSafe = (*i).myVLinkWait;
1742  myHaveToWaitOnNextLink = true;
1743  link->removeApproaching(this);
1744  break;
1745  }
1746  //
1747 #ifdef NO_TRACI
1748  const bool influencerPrio = false;
1749 #else
1750  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1751 #endif
1752  std::vector<const SUMOVehicle*> collectFoes;
1753  bool opened = yellow || influencerPrio ||
1754  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1758  ls == LINKSTATE_ZIPPER ? &collectFoes : 0);
1759  if (opened && getLaneChangeModel().getShadowLane() != 0) {
1760  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
1761  if (parallelLink != 0) {
1762  const SUMOReal shadowLatPos = getLateralPositionOnLane() - getLaneChangeModel().getShadowDirection() * 0.5 * (
1764  opened &= parallelLink->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1767  getWaitingTime(), shadowLatPos, 0);
1768 #ifdef DEBUG_EXEC_MOVE
1769  if (DEBUG_COND) std::cout
1770  << SIMTIME
1771  << " veh=" << getID()
1772  << " shadowLane=" << getLaneChangeModel().getShadowLane()->getID()
1773  << " shadowDir=" << getLaneChangeModel().getShadowDirection()
1774  << " parallelLink=" << (parallelLink == 0 ? "NULL" : parallelLink->getViaLaneOrLane()->getID())
1775  << " opened=" << opened
1776  << "\n";
1777 #endif
1778  }
1779  }
1780  // vehicles should decelerate when approaching a minor link
1781  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont()) {
1782  SUMOReal visibilityDistance = link->getFoeVisibilityDistance();
1783  SUMOReal determinedFoePresence = i->myDistance <= visibilityDistance;
1784  if (!determinedFoePresence) {
1785  vSafe = (*i).myVLinkWait;
1786  myHaveToWaitOnNextLink = true;
1787  if (ls == LINKSTATE_EQUAL) {
1788  link->removeApproaching(this);
1789  }
1790  break;
1791  } else {
1792  // past the point of no return. we need to drive fast enough
1793  // to make it across the link. However, minor slowdowns
1794  // should be permissible to follow leading traffic safely
1795  // XXX: There is a problem in subsecond simulation: If we cannot
1796  // make it across the minor link in one step, new traffic
1797  // could appear on a major foe link and cause a collision. Refs. #1845, #2123
1798  vSafeMinDist = myLane->getLength() - getPositionOnLane(); // distance that must be covered
1800  vSafeMin = MIN2((SUMOReal) DIST2SPEED(vSafeMinDist + POSITION_EPS), (*i).myVLinkPass);
1801  } else {
1802  vSafeMin = MIN2((SUMOReal) DIST2SPEED(2 * vSafeMinDist + NUMERICAL_EPS) - getSpeed(), (*i).myVLinkPass);
1803  }
1804  }
1805  }
1806  // have waited; may pass if opened...
1807  if (opened) {
1808  vSafe = (*i).myVLinkPass;
1809  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1810  // this vehicle is probably not gonna drive across the next junction (heuristic)
1811  myHaveToWaitOnNextLink = true;
1812  }
1813  } else if (link->getState() == LINKSTATE_ZIPPER) {
1814  vSafeZipper = MIN2(vSafeZipper,
1815  link->getZipperSpeed(this, (*i).myDistance, (*i).myVLinkPass, (*i).myArrivalTime, &collectFoes));
1816  } else {
1817  vSafe = (*i).myVLinkWait;
1818  myHaveToWaitOnNextLink = true;
1819  if (ls == LINKSTATE_EQUAL) {
1820  link->removeApproaching(this);
1821  }
1822 #ifdef DEBUG_EXEC_MOVE
1823  if (DEBUG_COND) {
1824  std::cout << SIMTIME << " braking for closed link=" << link->getViaLaneOrLane()->getID() << "\n";
1825  }
1826 #endif
1827  break;
1828  }
1829  } else {
1830  // we have: i->link == 0 || !i->setRequest
1831  vSafe = (*i).myVLinkWait;
1832  if (vSafe < getSpeed()) {
1833  myHaveToWaitOnNextLink = true;
1834  }
1835  break;
1836  }
1837  }
1838 
1839 //#ifdef DEBUG_EXEC_MOVE
1840 // if (DEBUG_COND) {
1841 // std::cout << "\nvCurrent = " << toString(getSpeed(), 24) << "" << std::endl;
1842 // std::cout << "vSafe = " << toString(vSafe, 24) << "" << std::endl;
1843 // std::cout << "vSafeMin = " << toString(vSafeMin, 24) << "" << std::endl;
1844 // std::cout << "vSafeMinDist = " << toString(vSafeMinDist, 24) << "" << std::endl;
1845 //
1846 // SUMOReal gap = getLeader().second;
1847 // std::cout << "gap = " << toString(gap, 24) << std::endl;
1848 // std::cout << "vSafeStoppedLeader = " << toString(getCarFollowModel().stopSpeed(this, getSpeed(), gap), 24)
1849 // << "\n" << std::endl;
1850 // }
1851 //#endif
1852 
1853  if ((MSGlobals::gSemiImplicitEulerUpdate && vSafe + NUMERICAL_EPS < vSafeMin)
1854  || (!MSGlobals::gSemiImplicitEulerUpdate && (vSafe + NUMERICAL_EPS < vSafeMin && vSafeMin != 0))) { // this might be good for the euler case as well
1855  // cannot drive across a link so we need to stop before it
1856  // XXX: (Leo) This often called stopSpeed with vSafeMinDist==0 (for the ballistic update), since vSafe can become negative
1857  // For the Euler update the term '+ NUMERICAL_EPS' prevented a call here... Recheck, consider of -INVALID_SPEED instead of 0 to indicate absence of vSafeMin restrictions. Refs. #2577
1858  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1859  vSafeMin = 0;
1860  myHaveToWaitOnNextLink = true;
1861 
1862 #ifdef DEBUG_EXEC_MOVE
1863  if (DEBUG_COND) {
1864  std::cout << "vSafeMin Problem?" << std::endl;
1865  }
1866 #endif
1867 
1868  }
1869 
1870  // vehicles inside a roundabout should maintain their requests
1871  if (myLane->getEdge().isRoundabout()) {
1872  myHaveToWaitOnNextLink = false;
1873  }
1874 
1875  vSafe = MIN2(vSafe, vSafeZipper);
1876 
1877 //#ifdef DEBUG_EXEC_MOVE
1878 // if (DEBUG_COND) {
1879 // std::cout << "vSafe = " << toString(vSafe,12) << "\n" << std::endl;
1880 // }
1881 //#endif
1882 
1883  // XXX braking due to lane-changing and processing stops is not registered
1884  // To avoid casual blinking brake lights at high speeds due to dawdling of the
1885  // leading vehicle, we don't show brake lights when the deceleration could be caused
1886  // by frictional forces and air resistance (i.e. proportional to v^2, coefficient could be adapted further)
1887  SUMOReal pseudoFriction = (0.05 + 0.005 * getSpeed()) * getSpeed();
1888  bool brakelightsOn = vSafe < getSpeed() - ACCEL2SPEED(pseudoFriction);
1889 
1890  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
1891  SUMOReal vNext;
1893  vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1894  } else {
1895  // in case of ballistic position update, negative speeds can indicate desired stops within next timestep.
1896  if (vSafeMin == 0) {
1897  // (Leo) This should be an indication that it would even be safe to stop immediately ("implicit Euler logic")
1898  // Hence, stopping within next the timestep (negative vNext) is tolerated.
1899  vNext = getCarFollowModel().moveHelper(this, vSafe);
1900  } else {
1901  vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1902  }
1903  // (Leo) to avoid oscillations (< 1e-10) of vNext in a standing vehicle column, we cap off vNext
1904  if (fabs(vNext) < NUMERICAL_EPS) {
1905  vNext = 0.;
1906  }
1907  }
1908 #ifdef DEBUG_EXEC_MOVE
1909  if (DEBUG_COND) {
1910  std::cout << SIMTIME << " moveHelper vSafe=" << vSafe << " vSafeMin=" << vSafeMin << " vNext=" << vNext << "\n";
1911  }
1912 #endif
1913 
1914  // vNext may be higher than vSafe without implying a bug:
1915  // - when approaching a green light that suddenly switches to yellow
1916  // - when using unregulated junctions
1917  // - when using tau < step-size
1918  // - when using unsafe car following models
1919  // - when using TraCI and some speedMode / laneChangeMode settings
1920  //if (vNext > vSafe + NUMERICAL_EPS) {
1921  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1922  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
1923  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1924  //}
1925 
1927  vNext = MAX2(vNext, (SUMOReal) 0.);
1928  } else {
1929  // (Leo) Ballistic: negative vNext can be used to indicate a stop within next step.
1930  // moveHelper() should take care of any bounds on the possible deceleration and
1931  // restrict negativity of vNext, e.g., vNext = MAX2(vNext, myState.mySpeed - ACCEL2SPEED(getCarFollowModel().getMaxDecel()));
1932  }
1933 
1934 #ifndef NO_TRACI
1935  if (myInfluencer != 0) {
1936  if (myInfluencer->isVTDControlled()) {
1937  vNext = myInfluencer->implicitSpeedVTD(this, myState.mySpeed);
1938  }
1940  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1941  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1942  }
1943 #endif
1944  // visit waiting time
1945  if (vNext <= SUMO_const_haltingSpeed && !isStopped()) {
1948  brakelightsOn = true;
1949  } else {
1950  myWaitingTime = 0;
1952  }
1953 
1954  if (brakelightsOn) {
1956  } else {
1958  }
1959 
1960  // update position and speed
1961  updateState(vNext);
1962  std::vector<MSLane*> passedLanes;
1963  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1964  passedLanes.push_back(*i);
1965  }
1966  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1967  passedLanes.push_back(myLane);
1968  }
1969  bool moved = false; // whether this veh moves to another lane
1970  std::string emergencyReason = " for unknown reasons";
1971  // move on lane(s)
1972  if (myState.myPos > myLane->getLength()) {
1973  // we are moving at least to the next lane (maybe pass even more than one)
1974  if (myCurrEdge != myRoute->end() - 1) {
1975  MSLane* approachedLane = myLane;
1976  // move the vehicle forward
1977  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1979  MSLink* link = (*i).myLink;
1980  // check whether the vehicle was allowed to enter lane
1981  // otherwise it is decelerated and we do not need to test for it's
1982  // approach on the following lanes when a lane changing is performed
1983  // proceed to the next lane
1984  if (link != 0) {
1985  approachedLane = link->getViaLaneOrLane();
1986 #ifndef NO_TRACI
1988 #endif
1989  if (link->getState() == LINKSTATE_TL_RED) {
1990  emergencyReason = " because of a red traffic light";
1991  break;
1992  }
1993 #ifndef NO_TRACI
1994  }
1995 #endif
1996  } else {
1997  emergencyReason = " because there is no connection to the next edge";
1998  approachedLane = 0;
1999  break;
2000  }
2001  if (approachedLane != myLane && approachedLane != 0) {
2002  myState.myPos -= myLane->getLength();
2003  assert(myState.myPos > 0);
2004  enterLaneAtMove(approachedLane);
2005  myLane = approachedLane;
2006 #ifdef HAVE_INTERNAL_LANES
2008  // erase leaders when past the junction
2009  if (link->getViaLane() == 0) {
2010  link->passedJunction(this);
2011  }
2012  }
2013 #endif
2014  if (hasArrived()) {
2015  break;
2016  }
2017  if (getLaneChangeModel().isChangingLanes()) {
2018  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
2019  // abort lane change
2020  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
2021  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2023  }
2024  }
2025  moved = true;
2026  if (approachedLane->getEdge().isVaporizing()) {
2028  break;
2029  }
2030  }
2031  passedLanes.push_back(approachedLane);
2032  }
2033  }
2034  }
2035 
2036  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
2037  if (myState.myPos > myLane->getLength()) {
2038  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
2039  + "'" + emergencyReason
2040  + " (decel=" + toString(myAcceleration - myState.mySpeed)
2041  + ", offset = " + toString(myState.myPos - myLane->getLength())
2042  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2045  myState.mySpeed = 0;
2046  }
2047  const MSLane* oldBackLane = getBackLane();
2048  if (getLaneChangeModel().isOpposite()) {
2049  passedLanes.clear(); // ignore back occupation
2050  }
2052  updateBestLanes();
2053  // bestLanes need to be updated before lane changing starts
2054  if (getLaneChangeModel().getShadowLane() != 0 && (moved || oldBackLane != getBackLane())) {
2056  }
2057  setBlinkerInformation(); // needs updated bestLanes
2058  //change the blue light only for emergency vehicles SUMOVehicleClass
2059  if (myType->getVehicleClass() == SVC_EMERGENCY) {
2060  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
2061  }
2062  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
2064  myAngle = computeAngle();
2065  }
2066 
2067 #ifdef DEBUG_EXEC_MOVE
2068  if (DEBUG_COND) {
2069  std::cout << SIMTIME << " executeMove finished veh=" << getID() << " lane=" << myLane->getID() << " myPos=" << getPositionOnLane() << " myPosLat=" << getLateralPositionOnLane() << "\n";
2070  }
2071 #endif
2072  if (getLaneChangeModel().isOpposite()) {
2073  // transform back to the opposite-direction lane
2074  if (myLane->getOpposite() == 0) {
2075  WRITE_WARNING("Unexpected end of opposite lane for vehicle '" + getID() + " at lane '" + myLane->getID() + "', time=" +
2076  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2078  } else {
2080  myLane = myLane->getOpposite();
2082  }
2083  }
2085  return moved;
2086 }
2087 
2088 
2089 void
2091  // update position and speed
2092  SUMOReal deltaPos; // positional change
2094  deltaPos = SPEED2DIST(vNext);
2095  } else {
2096  // ballistic
2097  // XXX: this is ok for the euler update, too. However, small differences
2098  // will to the above formula result from rounding. (introduced this too have
2099  // exact cooincidence of test results, refactor after merge to trunk)
2100  deltaPos = getDeltaPos(SPEED2ACCEL(vNext - myState.mySpeed));
2101  }
2102 
2103  // the *mean* acceleration during the next step (probably most appropriate for emission calculation)
2104  // TODO: recheck, approve, refs. #2579
2105  // NOTE: for the ballistic update this is in general
2106  // not equal to vNext - myState.mySpeed
2108 
2109 //#ifdef DEBUG_EXEC_MOVE
2110 // if (DEBUG_COND) {
2111 // std::cout << "deltaPos = " << deltaPos << std::endl;
2112 // }
2113 //#endif
2114 
2116  myState.mySpeed = MAX2(vNext, (SUMOReal)0.);
2117 
2118 #ifndef NO_TRACI
2119  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
2120  deltaPos = myInfluencer->implicitDeltaPosVTD(this);
2121  }
2122 #endif
2123 
2124  if (getLaneChangeModel().isOpposite()) {
2125  // transform to the forward-direction lane, move and then transform back
2127  myLane = myLane->getOpposite();
2128  }
2129  myState.myPos += deltaPos;
2130  myState.myLastCoveredDist = deltaPos;
2131 
2133 }
2134 
2135 
2136 const MSLane*
2138  if (myFurtherLanes.size() > 0) {
2139  return myFurtherLanes.back();
2140  } else {
2141  return myLane;
2142  }
2143 }
2144 
2145 
2146 SUMOReal
2147 MSVehicle::updateFurtherLanes(std::vector<MSLane*>& furtherLanes, std::vector<SUMOReal>& furtherLanesPosLat,
2148  const std::vector<MSLane*>& passedLanes) {
2149 
2150  // XXX only reset / set the values that were changed
2151 #ifdef DEBUG_FURTHER
2152  if (DEBUG_COND) std::cout << SIMTIME
2153  << " updateFurtherLanes oldFurther=" << toString(furtherLanes)
2154  << " oldFurtherPosLat=" << toString(furtherLanesPosLat)
2155  << " passed=" << toString(passedLanes)
2156  << "\n";
2157 #endif
2158  for (std::vector<MSLane*>::iterator i = furtherLanes.begin(); i != furtherLanes.end(); ++i) {
2159  (*i)->resetPartialOccupation(this);
2160  }
2161  const MSLane* firstOldFurther = furtherLanes.size() > 0 ? furtherLanes.front() : 0;
2162  // update furtherLanes
2164  furtherLanes.clear();
2165  if (passedLanes.size() > 0) {
2166  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
2167  std::vector<MSLane*>::const_reverse_iterator i = passedLanes.rbegin() + 1;
2168  while (leftLength > 0 && i != passedLanes.rend()) {
2169  furtherLanes.push_back(*i);
2170  if (*i != firstOldFurther) {
2171  furtherLanesPosLat.insert(furtherLanesPosLat.begin(), myState.myPosLat);
2172  }
2173 #ifdef DEBUG_FURTHER
2174  if (DEBUG_COND) {
2175  std::cout << SIMTIME << " updateFurtherLanes \n";
2176  }
2177 #endif
2178  leftLength -= (*i)->setPartialOccupation(this);
2179  ++i;
2180  }
2181  result = -leftLength;
2182  }
2183  assert(furtherLanesPosLat.size() >= furtherLanes.size());
2184  furtherLanesPosLat.erase(furtherLanesPosLat.begin() + furtherLanes.size(), furtherLanesPosLat.end());
2185  assert(furtherLanesPosLat.size() == furtherLanes.size());
2186 #ifdef DEBUG_FURTHER
2187  if (DEBUG_COND) std::cout
2188  << " newFurther=" << toString(furtherLanes)
2189  << " newFurtherPosLat=" << toString(furtherLanesPosLat)
2190  << " newBackPos=" << result
2191  << "\n";
2192 #endif
2193  return result;
2194 }
2195 
2196 
2197 SUMOReal
2199 #ifdef DEBUG_FURTHER
2200  //if (DEBUG_COND) std::cout << SIMTIME
2201  // << " getBackPositionOnLane veh=" << getID()
2202  // << " lane=" << Named::getIDSecure(lane)
2203  // << " myLane=" << myLane->getID()
2204  // << " further=" << toString(myFurtherLanes)
2205  // << " furtherPosLat=" << toString(myFurtherLanesPosLat)
2206  // << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
2207  // << " shadowFurther=" << toString(getLaneChangeModel().getShadowFurtherLanes())
2208  // << " shadowFurtherPosLat=" << toString(getLaneChangeModel().getShadowFurtherLanesPosLat())
2209  // << "\n";
2210 #endif
2211  if (lane == myLane
2212  || lane == getLaneChangeModel().getShadowLane()) {
2213  if (getLaneChangeModel().isOpposite()) {
2214  return myState.myPos + myType->getLength();
2215  } else {
2216  return myState.myPos - myType->getLength();
2217  }
2218  } else if ((myFurtherLanes.size() > 0 && lane == myFurtherLanes.back())
2219  || (getLaneChangeModel().getShadowFurtherLanes().size() > 0 && lane == getLaneChangeModel().getShadowFurtherLanes().back())
2220  ) {
2221  return myState.myBackPos;
2222  } else {
2223  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myFurtherLanes=" << toString(myFurtherLanes) << "\n";
2224  SUMOReal leftLength = myType->getLength() - myState.myPos;
2225  std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin();
2226  while (leftLength > 0 && i != myFurtherLanes.end()) {
2227  leftLength -= (*i)->getLength();
2228  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2229  if (*i == lane) {
2230  return -leftLength;
2231  }
2232  ++i;
2233  }
2234  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
2235  leftLength = myType->getLength() - myState.myPos;
2236  i = getLaneChangeModel().getShadowFurtherLanes().begin();
2237  while (leftLength > 0 && i != getLaneChangeModel().getShadowFurtherLanes().end()) {
2238  leftLength -= (*i)->getLength();
2239  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2240  if (*i == lane) {
2241  return -leftLength;
2242  }
2243  ++i;
2244  }
2245  assert(false);
2246  throw ProcessError("Request backPos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
2247  }
2248 }
2249 
2250 
2251 SUMOReal
2253  return getBackPositionOnLane(lane) + myType->getLength();
2254 }
2255 
2256 
2257 bool
2258 MSVehicle::isFrontOnLane(const MSLane* lane) const {
2259  return lane == myLane || lane == getLaneChangeModel().getShadowLane();
2260 }
2261 
2262 
2263 SUMOReal
2264 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
2265  SUMOReal lengths = 0;
2266  const MSLane::VehCont& vehs = l->getVehiclesSecure();
2267  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2268  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()
2269  // @todo recheck
2270  && (*i)->isFrontOnLane(l)) {
2271  foundStopped = true;
2272  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
2273  l->releaseVehicles();
2274  return ret;
2275  }
2276  lengths += (*i)->getVehicleType().getLengthWithGap();
2277  }
2278  l->releaseVehicles();
2279  return l->getLength() - lengths;
2280 }
2281 
2282 
2283 void
2284 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
2285 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2286  if (gDebugSelectedVehicle == getID()) {
2287  int bla = 0;
2288  }
2289 #endif
2290 #ifdef HAVE_INTERNAL_LANES
2292  bool hadVehicle = false;
2293  SUMOReal seenSpace = -lengthsInFront;
2294 
2295  bool foundStopped = false;
2296  // compute available space until a stopped vehicle is found
2297  // this is the sum of non-interal lane length minus in-between vehicle lenghts
2298  for (int i = 0; i < (int)lfLinks.size(); ++i) {
2299  // skip unset links
2300  DriveProcessItem& item = lfLinks[i];
2301  if (item.myLink == 0 || foundStopped) {
2302  item.availableSpace = seenSpace;
2303  item.hadVehicle = hadVehicle;
2304  continue;
2305  }
2306  // get the next lane, determine whether it is an internal lane
2307  const MSLane* approachedLane = item.myLink->getViaLane();
2308  if (approachedLane != 0) {
2309  if (item.myLink->hasFoes() && item.myLink->keepClear()/* && item.myLink->willHaveBlockedFoe()*/) {
2310  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
2311  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2312  } else {
2313  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2314  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2315  }
2316  item.availableSpace = seenSpace;
2317  item.hadVehicle = hadVehicle;
2318 #ifdef DEBUG_PLAN_MOVE
2319  if (DEBUG_COND) std::cout
2320  << SIMTIME
2321  << " veh=" << getID()
2322  << " approached=" << approachedLane->getID()
2323  << " approachedBrutto=" << approachedLane->getBruttoVehLenSum()
2324  << " avail=" << item.availableSpace
2325  << " seenSpace=" << seenSpace
2326  << " hadVehicle=" << item.hadVehicle
2327  << " lengthsInFront=" << lengthsInFront
2328  << "\n";
2329 #endif
2330  continue;
2331  }
2332  approachedLane = item.myLink->getLane();
2333  const MSVehicle* last = approachedLane->getLastAnyVehicle();
2334  if (last == 0) {
2335  seenSpace += approachedLane->getLength();
2336  item.availableSpace = seenSpace;
2337  } else if (!last->isFrontOnLane(approachedLane)) {
2340  item.availableSpace = MAX2(seenSpace, seenSpace + last->getBackPositionOnLane(approachedLane) + last->getCarFollowModel().brakeGap(last->getSpeed()));
2341  hadVehicle = true;
2343  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2345  if (last->myHaveToWaitOnNextLink) {
2346  foundStopped = true;
2347  }
2348 #ifdef DEBUG_PLAN_MOVE
2349  if (DEBUG_COND) std::cout
2350  << SIMTIME
2351  << " veh=" << getID()
2352  << " approached=" << approachedLane->getID()
2353  << " lastPoc=" << last->getID()
2354  << " avail=" << item.availableSpace
2355  << " seenSpace=" << seenSpace
2356  << " foundStopped=" << foundStopped
2357  << "\n";
2358 #endif
2359  } else {
2360 
2361  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
2362  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(last->getSpeed());
2363  const SUMOReal lastGap = last->getBackPositionOnLane(approachedLane) + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime()
2364  // gap of last up to the next intersection
2365  - last->getVehicleType().getMinGap();
2366  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
2367  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2368  } else {
2369  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
2370  item.availableSpace = seenSpace;
2371  }
2372  if (last->myHaveToWaitOnNextLink) {
2373  foundStopped = true;
2374  }
2375  hadVehicle = true;
2376 #ifdef DEBUG_PLAN_MOVE
2377  if (DEBUG_COND) std::cout
2378  << SIMTIME
2379  << " veh=" << getID()
2380  << " approached=" << approachedLane->getID()
2381  << " last=" << last->getID()
2382  << " avail=" << item.availableSpace
2383  << " seenSpace=" << seenSpace
2384  << " foundStopped=" << foundStopped
2385  << "\n";
2386 #endif
2387  }
2388  item.hadVehicle = hadVehicle;
2389  }
2390 
2391 
2392 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2393  if (gDebugSelectedVehicle == getID()) {
2394  int bla = 0;
2395  }
2396 #endif
2397  // check which links allow continuation and add pass available to the previous item
2398  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
2399  DriveProcessItem& item = lfLinks[i - 1];
2400  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
2401  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
2402 #ifndef NO_TRACI
2404 #endif
2405  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
2408  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
2409  if (!opened && item.myLink != 0) {
2410  if (i > 1) {
2411  DriveProcessItem& item2 = lfLinks[i - 2];
2412  if (item2.myLink != 0 && item2.myLink->isCont()) {
2413  allowsContinuation = true;
2414  }
2415  }
2416  }
2417  if (allowsContinuation) {
2418  item.availableSpace = lfLinks[i].availableSpace;
2419  }
2420  }
2421 
2422  // find removalBegin
2423  int removalBegin = -1;
2424  for (int i = 0; hadVehicle && i < (int)lfLinks.size() && removalBegin < 0; ++i) {
2425  // skip unset links
2426  const DriveProcessItem& item = lfLinks[i];
2427  if (item.myLink == 0) {
2428  continue;
2429  }
2430  /*
2431  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
2432  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
2433  removalBegin = lastLinkToInternal;
2434  }
2435  */
2436 
2437  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
2438  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
2439  SUMOReal impatienceCorrection = 0;
2440  /*
2441  if(item.myLink->getState()==LINKSTATE_MINOR) {
2442  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
2443  }
2444  */
2445  if (leftSpace < -impatienceCorrection / 10. && item.myLink->hasFoes() && item.myLink->keepClear()) {
2446  removalBegin = i;
2447  }
2448  //removalBegin = i;
2449  }
2450  }
2451  // abort requests
2452  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
2453  while (removalBegin < (int)(lfLinks.size())) {
2454  const SUMOReal brakeGap = getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.);
2455  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
2456  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
2457  lfLinks[removalBegin].mySetRequest = false;
2458  }
2459  ++removalBegin;
2460  }
2461  }
2462  }
2463 #else
2464  UNUSED_PARAMETER(lengthsInFront);
2465 #endif
2466  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2467  if ((*i).myLink != 0) {
2468  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
2469  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((int)2); // tie braker
2470  }
2471  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2472  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2473  }
2474  }
2475  if (getLaneChangeModel().getShadowLane() != 0) {
2476  // register on all shadow links
2477  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2478  if ((*i).myLink != 0) {
2479  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
2480  if (parallelLink != 0) {
2481  parallelLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2482  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2484  }
2485  }
2486  }
2487  }
2488 }
2489 
2490 
2491 void
2493  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2494  // skip the reminder if it is a lane reminder but not for my lane
2495  if (rem->first->getLane() != 0 && rem->second > 0.) {
2496 #ifdef _DEBUG
2497  if (myTraceMoveReminders) {
2498  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
2499  }
2500 #endif
2501  ++rem;
2502  } else {
2503  if (rem->first->notifyEnter(*this, reason)) {
2504 #ifdef _DEBUG
2505  if (myTraceMoveReminders) {
2506  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
2507  }
2508 #endif
2509  ++rem;
2510  } else {
2511 #ifdef _DEBUG
2512  if (myTraceMoveReminders) {
2513  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
2514  }
2515 #endif
2516  rem = myMoveReminders.erase(rem);
2517  }
2518  }
2519  }
2520 }
2521 
2522 
2523 bool
2524 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
2525  myAmOnNet = !onTeleporting;
2526  // vaporizing edge?
2527  /*
2528  if (enteredLane->getEdge().isVaporizing()) {
2529  // yep, let's do the vaporization...
2530  myLane = enteredLane;
2531  return true;
2532  }
2533  */
2534  // move mover reminder one lane further
2535  adaptLaneEntering2MoveReminder(*enteredLane);
2536  // set the entered lane as the current lane
2537  myLane = enteredLane;
2538  myLastBestLanesEdge = 0;
2539 
2540  // internal edges are not a part of the route...
2541  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
2542  ++myCurrEdge;
2543  }
2544  if (!onTeleporting) {
2546  } else {
2547  // normal move() isn't called so reset position here. must be done
2548  // before calling reminders
2549  // XXX: This seems strange to me since in activateReminders, which (e.g. for induction loops)
2550  // may call notifyEnter making use of the stored position to decide whether or not to add the vehicle...
2551  // Please recheck (Leo), refs. #2579
2552  myState.myPos = 0;
2555  }
2556  return hasArrived();
2557 }
2558 
2559 
2560 void
2562  myAmOnNet = true;
2563  myLane = enteredLane;
2565  // need to update myCurrentLaneInBestLanes
2566  updateBestLanes();
2567  // switch to and activate the new lane's reminders
2568  // keep OldLaneReminders
2569  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2570  addReminder(*rem);
2571  }
2573  MSLane* lane = myLane;
2574  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
2575  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
2576  if (lane != 0) {
2577  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
2578  }
2579  if (lane != 0) {
2580 #ifdef DEBUG_FURTHER
2581  if (DEBUG_COND) {
2582  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
2583  }
2584 #endif
2585  myFurtherLanes[i]->resetPartialOccupation(this);
2586  myFurtherLanes[i] = lane;
2588 #ifdef DEBUG_FURTHER
2589  if (DEBUG_COND) {
2590  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
2591  }
2592 #endif
2593  leftLength -= (lane)->setPartialOccupation(this);
2594  } else {
2595  // keep the old values, but ensure there is no shadow
2598  }
2599  }
2600  }
2601 #ifdef DEBUG_FURTHER
2602  if (DEBUG_COND) {
2603  std::cout << SIMTIME << " enterLaneAtLaneChange new furtherLanes=" << toString(myFurtherLanes) << "\n";
2604  }
2605 #endif
2606  myAngle = computeAngle();
2607 }
2608 
2609 
2610 void
2612  myState = State(pos, speed, posLat, pos - getVehicleType().getLength());
2613  if (myDeparture == NOT_YET_DEPARTED) {
2614  onDepart();
2615  }
2617  assert(myState.myPos >= 0);
2618  assert(myState.mySpeed >= 0);
2619  myWaitingTime = 0;
2620  myLane = enteredLane;
2621  myAmOnNet = true;
2622  if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
2623  // set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
2624  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2625  addReminder(*rem);
2626  }
2627  activateReminders(notification);
2628  }
2629  // build the list of lanes the vehicle is lapping into
2630  SUMOReal leftLength = myType->getLength() - pos;
2631  MSLane* clane = enteredLane;
2632  while (leftLength > 0) {
2633  clane = clane->getLogicalPredecessorLane();
2634  if (clane == 0 || clane == myLane) {
2635  break;
2636  }
2637  myFurtherLanes.push_back(clane);
2639  leftLength -= (clane)->setPartialOccupation(this);
2640  }
2641  myState.myBackPos = -leftLength;
2644  }
2645  myAngle = computeAngle();
2646  if (getLaneChangeModel().isOpposite()) {
2647  myAngle += M_PI;
2648  }
2649 }
2650 
2651 
2652 void
2654  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2655  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
2656 #ifdef _DEBUG
2657  if (myTraceMoveReminders) {
2658  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
2659  }
2660 #endif
2661  ++rem;
2662  } else {
2663 #ifdef _DEBUG
2664  if (myTraceMoveReminders) {
2665  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
2666  }
2667 #endif
2668  rem = myMoveReminders.erase(rem);
2669  }
2670  }
2672  // @note. In case of lane change, myFurtherLanes and partial occupation
2673  // are handled in enterLaneAtLaneChange()
2674  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
2675 #ifdef DEBUG_FURTHER
2676  if (DEBUG_COND) {
2677  std::cout << SIMTIME << " leaveLane \n";
2678  }
2679 #endif
2680  (*i)->resetPartialOccupation(this);
2681  }
2682  myFurtherLanes.clear();
2683  myFurtherLanesPosLat.clear();
2684  }
2685  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
2686  myAmOnNet = false;
2687  }
2689  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
2690  }
2692  while (!myStops.empty() && myStops.front().edge == myCurrEdge) {
2693  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
2694  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
2695  myStops.pop_front();
2696  }
2697  }
2698 }
2699 
2700 
2703  return *myLaneChangeModel;
2704 }
2705 
2706 
2709  return *myLaneChangeModel;
2710 }
2711 
2712 
2713 const std::vector<MSVehicle::LaneQ>&
2715  return *myBestLanes.begin();
2716 }
2717 
2718 
2719 void
2720 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
2721 #ifdef DEBUG_BESTLANES
2722  if (DEBUG_COND) {
2723  std::cout << SIMTIME << " updateBestLanes veh=" << getID() << " startLane1=" << Named::getIDSecure(startLane) << " myLane=" << Named::getIDSecure(myLane) << "\n";
2724  }
2725 #endif
2726 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2727  if (gDebugSelectedVehicle == getID()) {
2728  int bla = 0;
2729  myLastBestLanesEdge = 0;
2730  }
2731 #endif
2732  if (startLane == 0) {
2733  startLane = myLane;
2734  }
2735  assert(startLane != 0);
2736  if (getLaneChangeModel().isOpposite()) {
2737  return;
2738  }
2739  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
2741  return;
2742  }
2743  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
2744  if (myBestLanes.size() == 0 || forceRebuild) {
2745  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
2746  updateBestLanes(true, startLane->getLogicalPredecessorLane());
2747  }
2748  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
2749  return;
2750  }
2751  // adapt best lanes to fit the current internal edge:
2752  // keep the entries that are reachable from this edge
2753  const MSEdge* nextEdge = startLane->getInternalFollower();
2754  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
2755  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
2756  std::vector<LaneQ>& lanes = *it;
2757  assert(lanes.size() > 0);
2758  if (&(lanes[0].lane->getEdge()) == nextEdge) {
2759  // keep those lanes which are successors of internal lanes from the edge of startLane
2760  std::vector<LaneQ> oldLanes = lanes;
2761  lanes.clear();
2762  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
2763  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
2764  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
2765  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
2766  lanes.push_back(*it_lane);
2767  break;
2768  }
2769  }
2770  }
2771  assert(lanes.size() == startLane->getEdge().getLanes().size());
2772  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
2773  for (int i = 0; i < (int)lanes.size(); ++i) {
2774  if (i + lanes[i].bestLaneOffset < 0) {
2775  lanes[i].bestLaneOffset = -i;
2776  }
2777  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
2778  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
2779  }
2780  assert(i + lanes[i].bestLaneOffset >= 0);
2781  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
2782  if (lanes[i].bestContinuations[0] != 0) {
2783  // patch length of bestContinuation to match expectations (only once)
2784  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
2785  }
2786  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
2787  myCurrentLaneInBestLanes = lanes.begin() + i;
2788  }
2789  assert(&(lanes[i].lane->getEdge()) == nextEdge);
2790  }
2791  myLastBestLanesInternalLane = startLane;
2793  return;
2794  } else {
2795  // remove passed edges
2796  it = myBestLanes.erase(it);
2797  }
2798  }
2799  assert(false); // should always find the next edge
2800  }
2801  // start rebuilding
2802  myLastBestLanesEdge = &startLane->getEdge();
2803  myBestLanes.clear();
2804 
2805  // get information about the next stop
2806  const MSEdge* nextStopEdge = 0;
2807  const MSLane* nextStopLane = 0;
2808  SUMOReal nextStopPos = 0;
2809  if (!myStops.empty()) {
2810  const Stop& nextStop = myStops.front();
2811  nextStopLane = nextStop.lane;
2812  nextStopEdge = &nextStopLane->getEdge();
2813  nextStopPos = nextStop.startPos;
2814  }
2815  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
2816  nextStopEdge = *(myRoute->end() - 1);
2817  nextStopLane = nextStopEdge->getLanes()[myArrivalLane];
2818  nextStopPos = myArrivalPos;
2819  }
2820  if (nextStopEdge != 0) {
2821  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
2822  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
2823  nextStopPos = MAX2(POSITION_EPS, MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS)));
2824  }
2825 
2826  // go forward along the next lanes;
2827  int seen = 0;
2828  SUMOReal seenLength = 0;
2829  bool progress = true;
2830  for (MSRouteIterator ce = myCurrEdge; progress;) {
2831  std::vector<LaneQ> currentLanes;
2832  const std::vector<MSLane*>* allowed = 0;
2833  const MSEdge* nextEdge = 0;
2834  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
2835  nextEdge = *(ce + 1);
2836  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
2837  }
2838  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
2839  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
2840  LaneQ q;
2841  MSLane* cl = *i;
2842  q.lane = cl;
2843  q.bestContinuations.push_back(cl);
2844  q.bestLaneOffset = 0;
2845  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
2846  q.currentLength = q.length;
2847  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
2848  q.occupation = 0;
2849  q.nextOccupation = 0;
2850  currentLanes.push_back(q);
2851  }
2852  //
2853  if (nextStopEdge == *ce) {
2854  progress = false;
2855  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
2856  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
2857  (*q).allowsContinuation = false;
2858  (*q).length = nextStopPos;
2859  (*q).currentLength = (*q).length;
2860  }
2861  }
2862  }
2863 
2864  myBestLanes.push_back(currentLanes);
2865  ++seen;
2866  seenLength += currentLanes[0].lane->getLength();
2867  ++ce;
2868  progress &= (seen <= 4 || seenLength < 3000);
2869  progress &= seen <= 8;
2870  progress &= ce != myRoute->end();
2871  /*
2872  if(progress) {
2873  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
2874  }
2875  */
2876  }
2877 
2878  // we are examining the last lane explicitly
2879  if (myBestLanes.size() != 0) {
2880  SUMOReal bestLength = -1;
2881  int bestThisIndex = 0;
2882  int index = 0;
2883  std::vector<LaneQ>& last = myBestLanes.back();
2884  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2885  if ((*j).length > bestLength) {
2886  bestLength = (*j).length;
2887  bestThisIndex = index;
2888  }
2889  }
2890  index = 0;
2891  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2892  if ((*j).length < bestLength) {
2893  (*j).bestLaneOffset = bestThisIndex - index;
2894  }
2895  }
2896  }
2897 #ifdef DEBUG_BESTLANES
2898  if (DEBUG_COND) {
2899  std::cout << " last edge:\n";
2900  std::vector<LaneQ>& laneQs = myBestLanes.back();
2901  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
2902  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
2903  }
2904  }
2905 #endif
2906  // go backward through the lanes
2907  // track back best lane and compute the best prior lane(s)
2908  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
2909  std::vector<LaneQ>& nextLanes = (*(i - 1));
2910  std::vector<LaneQ>& clanes = (*i);
2911  MSEdge& cE = clanes[0].lane->getEdge();
2912  int index = 0;
2913  SUMOReal bestConnectedLength = -1;
2914  SUMOReal bestLength = -1;
2915  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
2916  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
2917  bestConnectedLength = (*j).length;
2918  }
2919  if (bestLength < (*j).length) {
2920  bestLength = (*j).length;
2921  }
2922  }
2923  // compute index of the best lane (highest length and least offset from the best next lane)
2924  int bestThisIndex = 0;
2925  if (bestConnectedLength > 0) {
2926  index = 0;
2927  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2928  LaneQ bestConnectedNext;
2929  bestConnectedNext.length = -1;
2930  if ((*j).allowsContinuation) {
2931  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
2932  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2933  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
2934  bestConnectedNext = *m;
2935  }
2936  }
2937  }
2938  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
2939  (*j).length += bestLength;
2940  } else {
2941  (*j).length += bestConnectedNext.length;
2942  }
2943  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
2944  }
2945  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
2946  if (clanes[bestThisIndex].length < (*j).length
2947  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))
2948  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) == abs((*j).bestLaneOffset) &&
2949  nextLinkPriority(clanes[bestThisIndex].bestContinuations) < nextLinkPriority((*j).bestContinuations))
2950  ) {
2951  bestThisIndex = index;
2952  }
2953  }
2954 #ifdef DEBUG_BESTLANES
2955  if (DEBUG_COND) {
2956  std::cout << " edge=" << cE.getID() << "\n";
2957  std::vector<LaneQ>& laneQs = clanes;
2958  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
2959  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
2960  }
2961  }
2962 #endif
2963 
2964  } else {
2965  // only needed in case of disconnected routes
2966  int bestNextIndex = 0;
2967  int bestDistToNeeded = (int) clanes.size();
2968  index = 0;
2969  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2970  if ((*j).allowsContinuation) {
2971  int nextIndex = 0;
2972  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
2973  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2974  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
2975  bestDistToNeeded = abs((*m).bestLaneOffset);
2976  bestThisIndex = index;
2977  bestNextIndex = nextIndex;
2978  }
2979  }
2980  }
2981  }
2982  }
2983  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
2984  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
2985 
2986  }
2987  // set bestLaneOffset for all lanes
2988  index = 0;
2989  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2990  if ((*j).length < clanes[bestThisIndex].length
2991  || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))
2992  || (nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)
2993  ) {
2994  (*j).bestLaneOffset = bestThisIndex - index;
2995  if ((nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)) {
2996  // try to move away from the lower-priority lane before it ends
2997  (*j).length = (*j).currentLength;
2998  }
2999  } else {
3000  (*j).bestLaneOffset = 0;
3001  }
3002  }
3003  }
3005 #ifdef DEBUG_BESTLANES
3006  if (DEBUG_COND) {
3007  std::cout << SIMTIME << " veh=" << getID() << " bestCont=" << toString(getBestLanesContinuation()) << "\n";
3008  }
3009 #endif
3010  return;
3011 }
3012 
3013 
3014 int
3015 MSVehicle::nextLinkPriority(const std::vector<MSLane*>& conts) {
3016  if (conts.size() < 2) {
3017  return -1;
3018  } else {
3019  MSLink* link = MSLinkContHelper::getConnectingLink(*conts[0], *conts[1]);
3020  if (link != 0) {
3021  return link->havePriority() ? 1 : 0;
3022  } else {
3023  // disconnected route
3024  return -1;
3025  }
3026  }
3027 }
3028 
3029 
3030 void
3032  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
3033  std::vector<LaneQ>::iterator i;
3034  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
3035  SUMOReal nextOccupation = 0;
3036  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
3037  nextOccupation += (*j)->getBruttoVehLenSum();
3038  }
3039  (*i).nextOccupation = nextOccupation;
3040  if ((*i).lane == startLane) {
3042  }
3043  }
3044 }
3045 
3046 
3047 const std::vector<MSLane*>&
3049  if (myBestLanes.empty() || myBestLanes[0].empty()) {
3050  return myEmptyLaneVector;
3051  }
3052  return (*myCurrentLaneInBestLanes).bestContinuations;
3053 }
3054 
3055 
3056 const std::vector<MSLane*>&
3058  const MSLane* lane = l;
3059  // XXX: shouldn't this be a "while" to cover more than one internal lane? (Leo) Refs. #2575
3061  // internal edges are not kept inside the bestLanes structure
3062  lane = lane->getLinkCont()[0]->getLane();
3063  }
3064  if (myBestLanes.size() == 0) {
3065  return myEmptyLaneVector;
3066  }
3067  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
3068  if ((*i).lane == lane) {
3069  return (*i).bestContinuations;
3070  }
3071  }
3072  return myEmptyLaneVector;
3073 }
3074 
3075 
3076 int
3078  if (myBestLanes.empty() || myBestLanes[0].empty()) {
3079  return 0;
3080  } else {
3081  return (*myCurrentLaneInBestLanes).bestLaneOffset;
3082  }
3083 }
3084 
3085 
3086 void
3088  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
3089  assert(laneIndex < (int)preb.size());
3090  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
3091 }
3092 
3093 
3094 void
3096  if (MSGlobals::gLaneChangeDuration > 0 && !getLaneChangeModel().isChangingLanes()) {
3097  myState.myPosLat = 0;
3098  }
3099 }
3100 
3101 
3102 SUMOReal
3103 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) const {
3105  if (isOnRoad() && destEdge != NULL) {
3106  if (&myLane->getEdge() == *myCurrEdge) {
3107  // vehicle is on a normal edge
3108  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
3109  } else {
3110  // vehicle is on inner junction edge
3111  distance = myLane->getLength() - getPositionOnLane();
3112  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
3113  }
3114  }
3115  return distance;
3116 }
3117 
3118 
3119 std::pair<const MSVehicle* const, SUMOReal>
3121  if (myLane == 0) {
3122  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
3123  }
3124  if (dist == 0) {
3126  }
3127  const MSVehicle* lead = 0;
3128  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
3129  assert(vehs.size() > 0);
3130  MSLane::VehCont::const_iterator it = std::find(vehs.begin(), vehs.end(), this);
3131  if (it != vehs.end() && it + 1 != vehs.end()) {
3132  lead = *(it + 1);
3133  }
3134  if (lead != 0) {
3135  std::pair<const MSVehicle* const, SUMOReal> result(
3138  return result;
3139  }
3140  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
3141  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
3142  std::pair<const MSVehicle* const, SUMOReal> result = myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
3144  return result;
3145 }
3146 
3147 
3148 SUMOReal
3150  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader();
3151  if (leaderInfo.first == 0 || getSpeed() == 0) {
3152  return -1;
3153  }
3154  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
3155 }
3156 
3157 
3158 SUMOReal
3161 }
3162 
3163 
3164 SUMOReal
3167 }
3168 
3169 
3170 SUMOReal
3173 }
3174 
3175 
3176 SUMOReal
3179 }
3180 
3181 
3182 SUMOReal
3185 }
3186 
3187 
3188 SUMOReal
3191 }
3192 
3193 
3194 SUMOReal
3197 }
3198 
3199 
3200 SUMOReal
3203 }
3204 
3205 
3206 void
3208  if (myPersonDevice == 0) {
3210  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
3211  }
3213  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
3214  int numExpected = (int) myStops.front().awaitedPersons.size();
3215  if (numExpected != 0) {
3216  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
3217  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
3218  // Bus drivers usually do not know the names of the passengers.
3219  myStops.front().awaitedPersons.erase(person->getID());
3220  numExpected = (int) myStops.front().awaitedPersons.size();
3221  }
3222  if (numExpected == 0) {
3223  myStops.front().duration = 0;
3224  }
3225  }
3226 }
3227 
3228 void
3230  if (myContainerDevice == 0) {
3232  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
3233  }
3234  myContainerDevice->addTransportable(container);
3235  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
3236  int numExpected = (int) myStops.front().awaitedContainers.size();
3237  if (numExpected != 0) {
3238  myStops.front().awaitedContainers.erase(container->getID());
3239  numExpected = (int) myStops.front().awaitedContainers.size();
3240  }
3241  if (numExpected == 0) {
3242  myStops.front().duration = 0;
3243  }
3244  }
3245 }
3246 
3247 
3248 const std::vector<MSTransportable*>&
3250  if (myPersonDevice == 0) {
3252  } else {
3254  }
3255 }
3256 
3257 
3258 const std::vector<MSTransportable*>&
3260  if (myContainerDevice == 0) {
3262  } else {
3264  }
3265 }
3266 
3267 
3268 int
3270  int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
3271  return boarded + myParameter->personNumber;
3272 }
3273 
3274 int
3276  int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
3277  return loaded + myParameter->containerNumber;
3278 }
3279 
3280 
3281 void
3284  int state = getLaneChangeModel().getOwnState();
3285  if ((state & LCA_LEFT) != 0 && (state & LCA_SUBLANE) == 0) {
3287  } else if ((state & LCA_RIGHT) != 0 && (state & LCA_SUBLANE) == 0) {
3289  } else if (getLaneChangeModel().isChangingLanes()) {
3290  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
3292  } else {
3294  }
3295  } else {
3296  const MSLane* lane = getLane();
3297  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
3298  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
3299  switch ((*link)->getDirection()) {
3300  case LINKDIR_TURN:
3301  case LINKDIR_LEFT:
3302  case LINKDIR_PARTLEFT:
3304  break;
3305  case LINKDIR_RIGHT:
3306  case LINKDIR_PARTRIGHT:
3308  break;
3309  default:
3310  break;
3311  }
3312  }
3313  }
3314 
3315 }
3316 
3317 void
3319  if (currentTime % 1000 == 0) {
3322  } else {
3324  }
3325  }
3326 }
3327 
3328 
3329 void
3331  if (myType->amVehicleSpecific()) {
3332  delete myType;
3333  }
3334  myType = type;
3335 }
3336 
3337 int
3339  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
3340  return (int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
3341 }
3342 
3343 
3344 void
3346  assert(lane != 0);
3347  myLane = lane;
3348  myState.myPos = pos;
3349  myState.myPosLat = posLat;
3351 }
3352 
3353 
3354 SUMOReal
3356  return myState.myPosLat + 0.5 * myLane->getWidth() - 0.5 * getVehicleType().getWidth();
3357 }
3358 
3359 
3360 SUMOReal
3362  return getCenterOnEdge(lane) - 0.5 * getVehicleType().getWidth();
3363 }
3364 
3365 
3366 SUMOReal
3368  if (lane == 0 || &lane->getEdge() == &myLane->getEdge()) {
3369  return myLane->getRightSideOnEdge() + myState.myPosLat + 0.5 * myLane->getWidth();
3370  } else {
3371  assert(myFurtherLanes.size() == myFurtherLanesPosLat.size());
3372  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3373  if (myFurtherLanes[i] == lane) {
3374 #ifdef DEBUG_FURTHER
3375  if (DEBUG_COND) std::cout << " getCenterOnEdge veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " furtherLat=" << myFurtherLanesPosLat[i]
3376  << " result=" << lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth()
3377  << "\n";
3378 #endif
3379  return lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth();
3380  }
3381  }
3382  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3383  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3384  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3385  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
3386  if (shadowFurther[i] == lane) {
3387  assert(getLaneChangeModel().getShadowLane() != 0);
3388  return (lane->getRightSideOnEdge() + getLaneChangeModel().getShadowFurtherLanesPosLat()[i] + 0.5 * lane->getWidth()
3390  }
3391  }
3392  assert(false);
3393  throw ProcessError("Request lateral pos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3394  }
3395 }
3396 
3397 
3398 SUMOReal
3399 MSVehicle::getLatOffset(const MSLane* lane) const {
3400  assert(lane != 0);
3401  if (&lane->getEdge() == &myLane->getEdge()) {
3402  return myLane->getRightSideOnEdge() - lane->getRightSideOnEdge();
3403  } else {
3404  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3405  if (myFurtherLanes[i] == lane) {
3406 #ifdef DEBUG_FURTHER
3407  if (DEBUG_COND) {
3408  std::cout << " getLatOffset veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " posLat=" << myState.myPosLat << " furtherLat=" << myFurtherLanesPosLat[i] << "\n";
3409  }
3410 #endif
3412  }
3413  }
3414 #ifdef DEBUG_FURTHER
3415  if (DEBUG_COND) {
3416  std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3417  }
3418 #endif
3419  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3420  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3421  if (shadowFurther[i] == lane) {
3422 #ifdef DEBUG_FURTHER
3423  if (DEBUG_COND) std::cout << " getLatOffset veh=" << getID()
3424  << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
3425  << " lane=" << lane->getID()
3426  << " i=" << i
3427  << " posLat=" << myState.myPosLat
3428  << " shadowPosLat=" << getLatOffset(getLaneChangeModel().getShadowLane())
3429  << " shadowFurtherLat=" << getLaneChangeModel().getShadowFurtherLanesPosLat()[i]
3430  << "\n";
3431 #endif
3433  }
3434  }
3435  assert(false);
3436  throw ProcessError("Request lateral offset of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3437  }
3438 }
3439 
3440 
3441 SUMOReal
3443  return (fabs(getLateralPositionOnLane()) + 0.5 * getVehicleType().getWidth()
3444  - 0.5 * myLane->getWidth());
3445 }
3446 
3447 
3448 void
3450  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
3451  if ((*i).myLink != 0) {
3452  (*i).myLink->removeApproaching(this);
3453  }
3454  }
3455  // unregister on all shadow links
3457 }
3458 
3459 
3460 bool
3462  // the following links are unsafe:
3463  // - zipper links if they are close enough and have approaching vehicles in the relevant time range
3464  // - unprioritized links if the vehicle is currently approaching a prioritzed link and unable to stop in time
3466  const SUMOReal dist = getCarFollowModel().brakeGap(getSpeed(), getCarFollowModel().getMaxDecel(), 0);
3467  if (seen < dist) {
3468  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(lane);
3469  int view = 1;
3470  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3471  DriveItemVector::const_iterator di = myLFLinkLanes.begin();
3472  while (!lane->isLinkEnd(link) && seen <= dist) {
3473  if (!lane->getEdge().isInternal()
3474  && (((*link)->getState() == LINKSTATE_ZIPPER && seen < MSLink::ZIPPER_ADAPT_DIST)
3475  || !(*link)->havePriority())) {
3476  // find the drive item corresponding to this link
3477  bool found = false;
3478  while (di != myLFLinkLanes.end() && !found) {
3479  if ((*di).myLink != 0) {
3480  const MSLane* diPredLane = (*di).myLink->getApproachingLane();
3481  if (diPredLane != 0) {
3482  if (&diPredLane->getEdge() == &lane->getEdge()) {
3483  found = true;
3484  }
3485  }
3486  }
3487  if (!found) {
3488  di++;
3489  }
3490  }
3491  if (found) {
3492  const SUMOTime leaveTime = (*link)->getLeaveTime((*di).myArrivalTime, (*di).myArrivalSpeed,
3493  (*di).getLeaveSpeed(), getVehicleType().getLength());
3494  if ((*link)->hasApproachingFoe((*di).myArrivalTime, leaveTime, (*di).myArrivalSpeed, getCarFollowModel().getMaxDecel())) {
3495  //std::cout << SIMTIME << " veh=" << getID() << " aborting changeTo=" << Named::getIDSecure(bestLaneConts.front()) << " linkState=" << toString((*link)->getState()) << " seen=" << seen << " dist=" << dist << "\n";
3496  return true;
3497  }
3498  }
3499  // no drive item is found if the vehicle aborts it's request within dist
3500  }
3501  lane = (*link)->getViaLaneOrLane();
3502  if (!lane->getEdge().isInternal()) {
3503  view++;
3504  }
3505  seen += lane->getLength();
3506  link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3507  }
3508  }
3509  return false;
3510 }
3511 
3512 
3515  PositionVector centerLine;
3516  centerLine.push_back(getPosition());
3517  centerLine.push_back(getBackPosition());
3518  centerLine.move2side(0.5 * myType->getWidth());
3519  PositionVector result = centerLine;
3520  centerLine.move2side(-myType->getWidth());
3521  result.append(centerLine.reverse(), POSITION_EPS);
3522  return result;
3523 }
3524 
3525 
3528  // XXX implement more types
3529  switch (myType->getGuiShape()) {
3530  case SVS_PASSENGER:
3531  case SVS_PASSENGER_SEDAN:
3533  case SVS_PASSENGER_WAGON:
3534  case SVS_PASSENGER_VAN: {
3535  PositionVector result;
3536  PositionVector centerLine;
3537  centerLine.push_back(getPosition());
3538  centerLine.push_back(getBackPosition());
3539  PositionVector line1 = centerLine;
3540  PositionVector line2 = centerLine;
3541  line1.move2side(0.3 * myType->getWidth());
3542  line2.move2side(0.5 * myType->getWidth());
3543  line2.scaleRelative(0.8);
3544  result.push_back(line1[0]);
3545  result.push_back(line2[0]);
3546  result.push_back(line2[1]);
3547  result.push_back(line1[1]);
3548  line1.move2side(-0.6 * myType->getWidth());
3549  line2.move2side(-1.0 * myType->getWidth());
3550  result.push_back(line1[1]);
3551  result.push_back(line2[1]);
3552  result.push_back(line2[0]);
3553  result.push_back(line1[0]);
3554  return result;
3555  }
3556  default:
3557  return getBoundingBox();
3558  }
3559 }
3560 
3561 
3562 #ifndef NO_TRACI
3563 bool
3564 MSVehicle::addTraciStop(MSLane* const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until,
3565  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
3566  //if the stop exists update the duration
3567  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
3568  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
3569  if (duration == 0 && !iter->reached) {
3570  myStops.erase(iter);
3571  } else {
3572  iter->duration = duration;
3573  }
3574  return true;
3575  }
3576  }
3577 
3579  newStop.lane = lane->getID();
3580  newStop.startPos = startPos;
3581  newStop.endPos = endPos;
3582  newStop.duration = duration;
3583  newStop.until = until;
3584  newStop.triggered = triggered;
3585  newStop.containerTriggered = containerTriggered;
3586  newStop.parking = parking;
3587  newStop.index = STOP_INDEX_FIT;
3588  const bool result = addStop(newStop, errorMsg);
3589  if (myLane != 0) {
3590  updateBestLanes(true);
3591  }
3592  return result;
3593 }
3594 
3595 
3596 bool
3597 MSVehicle::addTraciBusOrContainerStop(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
3598  const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string& errorMsg) {
3599  //if the stop exists update the duration
3600  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
3601  const Named* const stop = isContainerStop ? (Named*)iter->containerstop : iter->busstop;
3602  if (stop != 0 && stop->getID() == stopId) {
3603  if (duration == 0 && !iter->reached) {
3604  myStops.erase(iter);
3605  } else {
3606  iter->duration = duration;
3607  }
3608  return true;
3609  }
3610  }
3611 
3613  MSStoppingPlace* bs = 0;
3614  if (isContainerStop) {
3615  newStop.containerstop = stopId;
3616  bs = MSNet::getInstance()->getContainerStop(stopId);
3617  if (bs == 0) {
3618  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
3619  return false;
3620  }
3621  } else {
3622  newStop.busstop = stopId;
3623  bs = MSNet::getInstance()->getBusStop(stopId);
3624  if (bs == 0) {
3625  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
3626  return false;
3627  }
3628  }
3629  newStop.duration = duration;
3630  newStop.until = until;
3631  newStop.triggered = triggered;
3632  newStop.containerTriggered = containerTriggered;
3633  newStop.parking = parking;
3634  newStop.index = STOP_INDEX_FIT;
3635  newStop.lane = bs->getLane().getID();
3636  newStop.endPos = bs->getEndLanePosition();
3637  newStop.startPos = bs->getBeginLanePosition();
3638  const bool result = addStop(newStop, errorMsg);
3639  if (myLane != 0) {
3640  updateBestLanes(true);
3641  }
3642  return result;
3643 }
3644 
3645 
3646 bool
3648  if (isStopped()) {
3652  }
3656  }
3657  // we have waited long enough and fulfilled any passenger-requirements
3658  if (myStops.front().busstop != 0) {
3659  // inform bus stop about leaving it
3660  myStops.front().busstop->leaveFrom(this);
3661  }
3662  // we have waited long enough and fulfilled any container-requirements
3663  if (myStops.front().containerstop != 0) {
3664  // inform container stop about leaving it
3665  myStops.front().containerstop->leaveFrom(this);
3666  }
3667  // the current stop is no longer valid
3669  myStops.pop_front();
3670  // do not count the stopping time towards gridlock time.
3671  // Other outputs use an independent counter and are not affected.
3672  myWaitingTime = 0;
3673  // maybe the next stop is on the same edge; let's rebuild best lanes
3674  updateBestLanes(true);
3675  // continue as wished...
3677  return true;
3678  }
3679  return false;
3680 }
3681 
3682 
3685  return myStops.front();
3686 }
3687 
3688 
3691  if (myInfluencer == 0) {
3692  myInfluencer = new Influencer();
3693  }
3694  return *myInfluencer;
3695 }
3696 
3697 
3698 const MSVehicle::Influencer*
3700  return myInfluencer;
3701 }
3702 
3703 
3704 SUMOReal
3706  if (myInfluencer != 0) {
3707  return myInfluencer->getOriginalSpeed();
3708  }
3709  return myState.mySpeed;
3710 }
3711 
3712 
3713 int
3715  if (hasInfluencer()) {
3717  MSNet::getInstance()->getCurrentTimeStep(),
3718  myLane->getEdge(),
3719  getLaneIndex(),
3720  state);
3721  }
3722  return state;
3723 }
3724 
3725 
3726 void
3728  myCachedPosition = xyPos;
3729 }
3730 
3731 #endif
3732 
3733 bool
3735  return myInfluencer != 0 && myInfluencer->isVTDControlled();
3736 }
3737 
3738 
3739 
3740 void
3743  // here starts the vehicle internal part (see loading)
3744  std::vector<SUMOTime> internals;
3745  internals.push_back(myDeparture);
3746  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
3747  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
3751  out.closeTag();
3752 }
3753 
3754 
3755 void
3756 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
3757  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
3758  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
3759  }
3760  int routeOffset;
3761  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
3762  bis >> myDeparture;
3763  bis >> routeOffset;
3764  if (hasDeparted()) {
3765  myDeparture -= offset;
3766  myCurrEdge += routeOffset;
3767  }
3771  // no need to reset myCachedPosition here since state loading happens directly after creation
3772 }
3773 
3774 /****************************************************************************/
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:1078
void setAngle(SUMOReal angle)
Set a custom vehicle angle in rad.
Definition: MSVehicle.cpp:817
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1445
The link is a partial left direction.
bool isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
Definition: MSVehicle.cpp:3734
#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's type.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:3330
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:302
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:2524
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:571
static int nextLinkPriority(const std::vector< MSLane * > &conts)
get a numerical value for the priority of the upcoming link
Definition: MSVehicle.cpp:3015
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:82
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1394
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1433
SUMOReal getMaxSpeed() const
Get vehicle's maximum speed [m/s].
long long int SUMOTime
Definition: SUMOTime.h:43
void planMove(const SUMOTime t, const MSLeaderInfo &ahead, const SUMOReal lengthsInFront)
Compute safe velocities for the upcoming lanes based on positions and speeds from the last time step...
Definition: MSVehicle.cpp:1226
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:117
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:810
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1461
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
int getVehicleNumber() const
Returns the number of vehicles on this lane (for which this lane is responsible)
Definition: MSLane.h:353
virtual std::string toString() const
print a debugging representation
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:1616
MoveReminderCont myMoveReminders
Currently relevant move reminders.
SUMOReal myArrivalPos
The position on the destination lane where the vehicle stops.
The action is due to the default of keeping right "Rechtsfahrgebot".
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
The action is done to help someone else.
const MSEdge * myLastBestLanesEdge
Definition: MSVehicle.h:1444
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:1034
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1442
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1472
const MSEdge * getInternalFollower() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1275
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1447
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:407
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:758
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1465
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1437
void setTentativeLaneAndPosition(MSLane *lane, SUMOReal pos, SUMOReal posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:3345
SUMOReal getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3361
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:3684
A lane area vehicles can halt at.
const std::vector< SUMOReal > & getShadowFurtherLanesPosLat() const
SUMOReal getMaxSpeed() const
Returns the maximum speed.
DriveItemVector myLFLinkLanes
Definition: MSVehicle.h:1545
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.h:112
void enterLaneAtInsertion(MSLane *enteredLane, SUMOReal pos, SUMOReal speed, SUMOReal posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:2611
bool resumeFromStopping()
Definition: MSVehicle.cpp:3647
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1475
bool hasInfluencer() const
Definition: MSVehicle.h:1359
SUMOTime duration
The stopping duration.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:192
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
SUMOReal maximumSafeStopSpeed(SUMOReal gap, SUMOReal currentSpeed, bool onInsertion=false, SUMOReal headway=-1) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:477
The speed is given.
SUMOReal getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:681
SUMOReal getImpatience() const
Returns this vehicles impatience.
void setBlinkerInformation()
Definition: MSVehicle.cpp:3282
#define M_PI
Definition: angles.h:37
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2500
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:3229
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1538
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
Definition: MSVehicle.cpp:3461
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1462
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:324
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:3705
The vehicle arrived at a junction.
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:422
bool isVTDControlled() const
Definition: MSVehicle.cpp:458
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:535
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle's follow speed (no dawdling)
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOReal getLength() const
Returns the lane's length.
Definition: MSLane.h:480
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:776
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:190
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:610
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:60
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
void updateState(SUMOReal vNext)
updates the vehicles state, given a next value for its speed. This value can be negative in case of t...
Definition: MSVehicle.cpp:2090
int getShadowDirection() const
return the direction in which the current shadow lane lies
The link is a 180 degree turn.
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
Wants go to the right.
SUMOReal getLength() const
Get vehicle's length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1543
SUMOReal currentLength
The length which may be driven on this lane.
Definition: MSVehicle.h:675
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1456
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:619
#define STOPPING_PLACE_OFFSET
Definition: MSVehicle.cpp:95
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:1163
SUMOReal implicitDeltaPosVTD(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new VTD position ...
Definition: MSVehicle.cpp:513
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:3171
SUMOReal getWidth() const
Returns the lane's width.
Definition: MSLane.h:496
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:804
const MSLane * getBackLane() const
Definition: MSVehicle.cpp:2137
void registerEmergencyStop()
register emergency stop
SUMOReal getEndLanePosition() const
Returns the end position of this stop.
void scaleRelative(SUMOReal factor)
enlarges/shrinks the polygon by a factor based at the centroid
State & operator=(const State &state)
Assignment operator.
Definition: MSVehicle.cpp:126
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:75
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:97
vehicle doesn't want to change
Definition: MSVehicle.h:223
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:1042
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
#define DEBUG_COND
Definition: MSVehicle.cpp:93
const MSRoute * myRoute
This Vehicle's route.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:59
const std::string & getID() const
returns the id of the transportable
bool hasDeparted() const
Returns whether this vehicle has already departed.
SUMOReal getCenterOnEdge() const
Definition: MSLane.h:905
The vehicle got vaporized.
void postProcessVTD(MSVehicle *v)
Definition: MSVehicle.cpp:469
SUMOReal estimateLeaveSpeed(const MSLink *const link, const SUMOReal vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:1558
SUMOTime until
The time at which the vehicle may continue its journey.
WaitingTimeCollector myWaitingTimeCollector
Definition: MSVehicle.h:1434
SUMOReal mySpeed
the stored speed (should be >=0 at any time)
Definition: MSVehicle.h:142
const int STOP_INDEX_FIT
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:778
This is an uncontrolled, right-before-left link.
render as a sedan passenger vehicle ("Stufenheck")
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:3159
void removeWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Removes a vehicle from the list of waiting vehicles to a given edge.
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1692
int getLaneIndex() const
Definition: MSVehicle.cpp:3338
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.
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:3120
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:374
int myArrivalLane
The destination lane where the vehicle stops.
const SUMOVehicleParameter * myParameter
This Vehicle'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:56
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1480
void adaptToLeaders(const MSLeaderInfo &ahead, SUMOReal latOffset, const SUMOReal seen, DriveProcessItem *const lastLink, const MSLane *const lane, SUMOReal &v, SUMOReal &vLinkPass) const
Definition: MSVehicle.cpp:1579
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1027
A storage for edge travel times and efforts.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:254
Wants go to the left.
const Position geometryPositionAtOffset(SUMOReal offset, SUMOReal lateralOffset=0) const
Definition: MSLane.h:444
This is an uncontrolled, all-way stop link.
The action is due to the wish to be faster (tactical lc)
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:673
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:839
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:63
SUMOReal getStoppingPosition(const SUMOVehicle *veh) const
For vehicles at the stop this gives the the actual stopping position of the vehicle. For all others the last free stopping position.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
#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:2561
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
SUMOReal myStopDist
distance to the next stop or -1 if there is none
Definition: MSVehicle.h:1486
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The simulated network and simulation perfomer.
Definition: MSNet.h:93
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
SUMOReal updateFurtherLanes(std::vector< MSLane * > &furtherLanes, std::vector< SUMOReal > &furtherLanesPosLat, const std::vector< MSLane * > &passedLanes)
update a vector of further lanes and return the new backPos
Definition: MSVehicle.cpp:2147
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:798
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
WaitingTimeCollector(SUMOTime memory=MSGlobals::gWaitingTimeMemory)
Constructor.
Definition: MSVehicle.cpp:157
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2702
#define SIMTIME
Definition: SUMOTime.h:70
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1619
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:380
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:95
SUMOTime getMinimalArrivalTime(SUMOReal dist, SUMOReal currentSpeed, SUMOReal arrivalSpeed) const
Computes the minimal time needed to cover a distance given the desired speed at arrival.
Definition: MSCFModel.cpp:234
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:1000
PositionVector reverse() const
reverse position vector
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:679
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:707
SUMOReal getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:406
SUMOReal getElectricityConsumption() const
Returns electricity consumption of the current state.
Definition: MSVehicle.cpp:3195
The vehicles starts to stop.
Definition: MSNet.h:555
void unregisterOneWaitingForContainer()
decreases the count of vehicles waiting for a container to allow recogniztion of container related de...
SUMOTime getMemorySize() const
Definition: MSVehicle.h:195
Needs to stay on the current lane.
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.
int getContainerNumber() const
Returns the number of containers.
Definition: MSVehicle.cpp:3275
WaitingTimeCollector & operator=(const WaitingTimeCollector &wt)
Assignment operator.
Definition: MSVehicle.cpp:162
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:279
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:138
static std::vector< MSTransportable * > myEmptyTransportableVector
Definition: MSVehicle.h:1450
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
The vehicle changes lanes (micro only) XXX: What if a vehicle changes lanes and passes a junction sim...
MSLane * lane
The described lane.
Definition: MSVehicle.h:671
void checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:2284
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:591
Left blinker lights are switched on.
Definition: MSVehicle.h:1002
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1954
#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:428
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver's reaction time, assuming that during...
Definition: MSCFModel.h:263
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
const MSLane & getLane() const
Returns the lane this stop is located at.
SUMOReal computeAngle() const
compute the current vehicle angle
Definition: MSVehicle.cpp:823
SUMOReal implicitSpeedVTD(const MSVehicle *veh, SUMOReal oldSpeed)
return the speed that is implicit in the new VTD position
Definition: MSVehicle.cpp:498
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:695
SUMOReal startPos
The stopping position start.
SUMOReal getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane ...
Definition: MSVehicle.cpp:3442
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:1793
The vehicle got a new route.
Definition: MSNet.h:549
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:716
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:789
vehicle want's to change to right lane
Definition: MSVehicle.h:227
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:100
void removeApproachingInformation(DriveItemVector &lfLinks) const
unregister approach from all upcoming links
Definition: MSVehicle.cpp:3449
The action is urgent (to be defined by lc-model)
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:786
render as a hatchback passenger vehicle ("Fliessheck")
Stores the waiting intervals over the previous seconds (memory is to be specified in ms...
Definition: MSVehicle.h:167
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3514
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.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:699
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:221
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle's current lane and their successors...
Definition: MSVehicle.cpp:3048
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
SUMOReal endPos
The stopping position end.
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:673
SUMOReal myAngle
the angle in radians (
Definition: MSVehicle.h:1483
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:2720
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:712
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:812
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
SUMOReal getMinimalArrivalSpeed(SUMOReal dist, SUMOReal currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance.
Definition: MSCFModel.cpp:247
Position myCachedPosition
Definition: MSVehicle.h:1488
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:307
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:1561
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:782
std::vector< SUMOReal > myFurtherLanesPosLat
Definition: MSVehicle.h:1466
const std::vector< MSLane * > & getShadowFurtherLanes() const
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:875
std::list< Stop > myStops
The vehicle's list of stops.
Definition: MSVehicle.h:1453
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
const int STOP_INDEX_END
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3527
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:1003
bool isStoppedInRange(SUMOReal pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:1021
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:1531
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1440
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:1244
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition) ...
Definition: MSVehicle.h:1478
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...
const MSLeaderInfo & getLastVehicleInformation(const MSVehicle *ego, SUMOReal latOffset, SUMOReal minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:834
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:1623
void resetRoutePosition(int index)
Definition: MSVehicle.cpp:685
const std::vector< MSTransportable * > & getContainers() const
retrieve riding containers
Definition: MSVehicle.cpp:3259
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1448
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:3103
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:1650
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:2264
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:794
bool isRoundabout() const
Definition: MSEdge.h:638
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:406
T MIN2(T a, T b)
Definition: StdDefs.h:69
SUMOReal myLastCoveredDist
Definition: MSVehicle.h:159
The link is a (hard) right direction.
The action is needed to follow the route (navigational lc)
#define POSITION_EPS
Definition: config.h:188
The brake lights are on.
Definition: MSVehicle.h:1006
void addTransportable(MSTransportable *transportable)
Add a passenger.
A blue emergency light is on.
Definition: MSVehicle.h:1022
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:669
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:3756
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:601
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: MSVehicle.h:808
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:73
render as a van
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
Definition: MSCFModel.h:201
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:396
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:340
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:3095
void getSubLanes(const MSVehicle *veh, SUMOReal latOffset, int &rightmost, int &leftmost) const
#define DEG2RAD(x)
Definition: GeomHelper.h:45
render as a passenger vehicle
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1430
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
virtual SUMOReal freeSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal seen, SUMOReal maxSpeed, const bool onInsertion=false) const
Computes the vehicle's safe speed without a leader.
Definition: MSCFModel.cpp:206
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:97
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
void planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector &lfLinks, SUMOReal &myStopDist) const
Definition: MSVehicle.cpp:1277
The link is a partial right direction.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons) ...
virtual SUMOReal getHeadwayTime() const
Get the driver's reaction time [s].
Definition: MSCFModel.h:220
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:1009
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2714
int getRoutePosition() const
Definition: MSVehicle.cpp:679
void setVTDControlled(Position xyPos, MSLane *l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:445
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
bool containerTriggered
whether an arriving container lets the vehicle continue
State(SUMOReal pos, SUMOReal speed, SUMOReal posLat, SUMOReal backPos)
Constructor.
Definition: MSVehicle.cpp:148
int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:3269
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:683
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:3201
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
Definition: MSVehicle.cpp:3249
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:92
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:46
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:3741
SUMOVehicleShape getGuiShape() const
Get this vehicle type's shape.
SUMOReal getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.h:1272
virtual SUMOReal moveHelper(MSVehicle *const veh, SUMOReal vPos) const
Applies interaction with stops and lane changing model influences.
Definition: MSCFModel.cpp:144
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:3177
SUMOReal getRightSideOnLane() const
Get the vehicle's lateral position on the lane:
Definition: MSVehicle.cpp:3355
std::string lane
The lane to stop at.
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:706
Influencer()
Constructor.
Definition: MSVehicle.cpp:235
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
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:2653
virtual void drawOutsideNetwork(bool)
register vehicle for drawing while outside the network
Definition: MSVehicle.h:1430
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
SUMOReal getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition: MSCFModel.h:193
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:3183
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:3165
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...
void updateOccupancyAndCurrentBestLane(const MSLane *startLane)
updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
Definition: MSVehicle.cpp:3031
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:3318
SUMOReal getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOReal getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane...
Definition: MSVehicle.cpp:3399
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2005
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1286
void registerOneWaitingForContainer()
increases the count of vehicles waiting for a container to allow recogniztion of container related de...
vehicle want's to change to left lane
Definition: MSVehicle.h:225
The vehicle starts or ends parking.
~Influencer()
Destructor.
Definition: MSVehicle.cpp:252
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:256
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3690
static MSDevice_Transportable * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into, const bool isContainer)
Build devices for the given vehicle, if needed.
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:1258
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:184
SUMOReal getSlope() const
Returns the slope of the road at vehicle's position.
Definition: MSVehicle.cpp:765
void setNoShadowPartialOccupator(MSLane *lane)
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:800
The link has yellow light, may pass.
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:416
void setVTDState(Position xyPos)
sets position outside the road network
Definition: MSVehicle.cpp:3727
void passTime(SUMOTime dt, bool waiting)
Definition: MSVehicle.cpp:197
SUMOReal occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:677
SUMOReal getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3367
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1469
void resetChanged()
reset the flag whether a vehicle already moved to false
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:685
SUMOReal interpolateLanePosToGeometryPos(SUMOReal lanePos) const
Definition: MSLane.h:438
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:300
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:806
SUMOReal myPreviousSpeed
the speed at the begin of the previous time step
Definition: MSVehicle.h:153
void onDepart()
Called when the vehicle is inserted into the network.
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:3189
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:1614
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:796
static SUMOReal gLateralResolution
Definition: MSGlobals.h:89
void setConsiderSafeVelocity(bool value)
Sets whether the safe velocity shall be regarded.
Definition: MSVehicle.cpp:404
MSStoppingPlace * getContainerStop(const std::string &id) const
Returns the named container stop.
Definition: MSNet.cpp:813
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false, bool check=false)
Replaces the current route by the given edges.
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:1216
int index
at which position in the stops list
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:780
const waitingIntervalList & getWaitingIntervals() const
Definition: MSVehicle.h:200
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling) ...
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:3597
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
The arrival lane is given.
int containerNumber
The static number of containers in the vehicle when it departs.
const std::string & getID() const
Returns the name of the vehicle type.
The vehicle ends to stop.
Definition: MSNet.h:557
SUMOReal getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:441
int myNumberReroutes
The number of reroutings.
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2258
SUMOReal departPos
(optional) The position the vehicle shall depart from
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to)
Informs all added listeners about a vehicle's state change.
Definition: MSNet.cpp:773
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:434
SUMOReal myPos
the stored position
Definition: MSVehicle.h:139
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:1015
SUMOReal getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
Definition: MSVehicle.cpp:2198
std::vector< DriveProcessItem > DriveItemVector
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1544
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:427
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:792
The action is due to a TraCI request.
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:232
SUMOReal getOppositePos(SUMOReal pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2509
void move2side(SUMOReal amount)
move position vector to side using certain ammount
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:802
vehicle want's to keep the current lane
Definition: MSVehicle.h:229
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
SUMOReal myPosLat
the stored lateral position
Definition: MSVehicle.h:145
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
SUMOReal getMinimalArrivalSpeedEuler(SUMOReal dist, SUMOReal currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance for Euler update...
Definition: MSCFModel.cpp:254
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1061
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:63
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1053
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSCFModel.cpp:468
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:3207
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1449
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:3087
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:161
SUMOReal myBackPos
the stored back position
Definition: MSVehicle.h:150
int getSpeedMode() const
return the current speed mode
Definition: MSVehicle.cpp:269
SUMOTime cumulatedWaitingTime(SUMOTime memory=-1) const
Definition: MSVehicle.cpp:176
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:263
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:578
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:1512
No information given; use default.
The link has yellow light, has to brake anyway.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:109
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:458
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:509
SUMOEmissionClass getEmissionClass() const
Get this vehicle type's emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:487
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:3714
void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
Definition: MSVehicle.cpp:2492
The edge is an internal edge.
Definition: MSEdge.h:97
public emergency vehicles
render as a wagon passenger vehicle ("Combi")
SUMOReal getTimeGap() const
Returns the time gap in seconds to the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:3149
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:86
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane's move reminders.
Definition: MSLane.h:228
int influenceChangeDecision(const SUMOTime currentTime, const MSEdge &currentEdge, const int currentLaneIndex, int state)
Applies stored LaneChangeMode information and laneTimeLine.
Definition: MSVehicle.cpp:312
SUMOReal getBackPositionOnLane() const
Get the vehicle's position relative to its current lane.
Definition: MSVehicle.h:398
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:3564
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:790
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:784
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle's internal edge travel times/efforts container.
Definition: MSVehicle.cpp:694
std::vector< MSDevice * > myDevices
The devices this vehicle has.
void adaptLaneEntering2MoveReminder(const MSLane &enteredLane)
Adapts the vehicle's entering of a new lane.
Definition: MSVehicle.cpp:745
Back-at-zero position.
The link has red light (must brake) but indicates upcoming green.
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:464
Interface for lane-change models.
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:3077
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
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:410
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:1459
std::string id
The vehicle's id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:802
static const Position INVALID
Definition: Position.h:261
The vehicle is being teleported.
SUMOReal getRightSideOnEdge() const
Definition: MSLane.h:897
const std::string & getID() const
Returns the name of the vehicle.
int size() const
Return the number of passengers / containers.
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
const Position getBackPosition() const
Definition: MSVehicle.cpp:851
SUMOReal getDeltaPos(SUMOReal accel)
calculates the distance covered in the next integration step given an acceleration and assuming the c...
Definition: MSVehicle.cpp:1670