SUMO - Simulation of Urban MObility
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-2017 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>
67 #include "MSVehicleControl.h"
68 #include "MSVehicleTransfer.h"
69 #include "MSGlobals.h"
70 #include "MSStoppingPlace.h"
71 #include "MSParkingArea.h"
73 #include "MSEdgeWeightsStorage.h"
75 #include "MSMoveReminder.h"
76 #include "MSTransportableControl.h"
77 #include "MSLane.h"
78 #include "MSJunction.h"
79 #include "MSVehicle.h"
80 #include "MSEdge.h"
81 #include "MSVehicleType.h"
82 #include "MSNet.h"
83 #include "MSRoute.h"
84 #include "MSLinkCont.h"
85 #include "MSLeaderInfo.h"
86 
87 // enable here and in utils/gui/globjects/GUIGLObjectPopupMenu.cpp
88 //#define DEBUG_VEHICLE_GUI_SELECTION 1
89 
90 //#define DEBUG_PLAN_MOVE
91 //#define DEBUG_EXEC_MOVE
92 //#define DEBUG_FURTHER
93 //#define DEBUG_STOPS
94 //#define DEBUG_BESTLANES
95 //#define DEBUG_IGNORE_RED
96 //#define DEBUG_COND (getID() == "ego")
97 //#define DEBUG_COND (isSelected())
98 
99 #define STOPPING_PLACE_OFFSET 0.5
100 
101 #define CRLL_LOOK_AHEAD 5
102 
103 // @todo Calibrate with real-world values / make configurable
104 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
105 
106 // ===========================================================================
107 // static value definitions
108 // ===========================================================================
109 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
110 std::vector<MSTransportable*> MSVehicle::myEmptyTransportableVector;
111 
112 
113 // ===========================================================================
114 // method definitions
115 // ===========================================================================
116 /* -------------------------------------------------------------------------
117  * methods of MSVehicle::State
118  * ----------------------------------------------------------------------- */
120  myPos = state.myPos;
121  mySpeed = state.mySpeed;
122  myPosLat = state.myPosLat;
123  myBackPos = state.myBackPos;
126 }
127 
128 
131  myPos = state.myPos;
132  mySpeed = state.mySpeed;
133  myPosLat = state.myPosLat;
134  myBackPos = state.myBackPos;
137  return *this;
138 }
139 
140 
141 bool
143  return (myPos != state.myPos ||
144  mySpeed != state.mySpeed ||
145  myPosLat != state.myPosLat ||
147  myPreviousSpeed != state.myPreviousSpeed ||
148  myBackPos != state.myBackPos);
149 }
150 
151 
152 MSVehicle::State::State(double pos, double speed, double posLat, double backPos) :
153  myPos(pos), mySpeed(speed), myPosLat(posLat), myBackPos(backPos), myPreviousSpeed(speed), myLastCoveredDist(SPEED2DIST(speed)) {}
154 
155 
156 
157 /* -------------------------------------------------------------------------
158  * methods of MSVehicle::WaitingTimeCollector
159  * ----------------------------------------------------------------------- */
160 
162 
164 
169  return *this;
170 }
171 
174  myWaitingIntervals.clear();
175  passTime(t, true);
176  return *this;
177 }
178 
179 SUMOTime
181  assert(memorySpan <= myMemorySize);
182  if (memorySpan == -1) {
183  memorySpan = myMemorySize;
184  }
185  SUMOTime totalWaitingTime = 0;
186  for (waitingIntervalList::const_iterator i = myWaitingIntervals.begin(); i != myWaitingIntervals.end(); i++) {
187  if (i->second >= memorySpan) {
188  if (i->first >= memorySpan) {
189  break;
190  } else {
191  totalWaitingTime += memorySpan - i->first;
192  }
193  } else {
194  totalWaitingTime += i->second - i->first;
195  }
196  }
197  return totalWaitingTime;
198 }
199 
200 void
202  waitingIntervalList::iterator i = myWaitingIntervals.begin();
203  waitingIntervalList::iterator end = myWaitingIntervals.end();
204  bool startNewInterval = i == end || (i->first != 0);
205  while (i != end) {
206  i->first += dt;
207  if (i->first >= myMemorySize) {
208  break;
209  }
210  i->second += dt;
211  i++;
212  }
213 
214  // remove intervals beyond memorySize
215  waitingIntervalList::iterator::difference_type d = std::distance(i, end);
216  while (d > 0) {
217  myWaitingIntervals.pop_back();
218  d--;
219  }
220 
221  if (!waiting) {
222  return;
223  } else if (!startNewInterval) {
224  myWaitingIntervals.begin()->first = 0;
225  } else {
226  myWaitingIntervals.push_front(std::make_pair(0, dt));
227  }
228  return;
229 }
230 
231 
232 
233 
234 
235 /* -------------------------------------------------------------------------
236  * methods of MSVehicle::Influencer
237  * ----------------------------------------------------------------------- */
238 #ifndef NO_TRACI
240  myLatDist(0),
241  mySpeedAdaptationStarted(true),
242  myConsiderSafeVelocity(true),
243  myConsiderMaxAcceleration(true),
244  myConsiderMaxDeceleration(true),
245  myRespectJunctionPriority(true),
246  myEmergencyBrakeRedLight(true),
247  myLastVTDAccess(-TIME2STEPS(20)),
248  myStrategicLC(LC_NOCONFLICT),
249  myCooperativeLC(LC_NOCONFLICT),
250  mySpeedGainLC(LC_NOCONFLICT),
251  myRightDriveLC(LC_NOCONFLICT),
252  mySublaneLC(LC_NOCONFLICT),
253  myTraciLaneChangePriority(LCP_URGENT),
254  myTraCISignals(-1),
255  myRoutingMode(0) {
256 }
257 
258 
260 
261 
262 void
263 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, double> >& speedTimeLine) {
265  mySpeedTimeLine = speedTimeLine;
266 }
267 
268 
269 void
270 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine) {
271  myLaneTimeLine = laneTimeLine;
272 }
273 
274 void
276  myLatDist = latDist;
277 }
278 
279 int
281  return (1 * myConsiderSafeVelocity +
286 }
287 
288 
289 int
291  return (1 * myStrategicLC +
292  4 * myCooperativeLC +
293  16 * mySpeedGainLC +
294  64 * myRightDriveLC +
296  1024 * mySublaneLC);
297 }
298 
299 
300 double
301 MSVehicle::Influencer::influenceSpeed(SUMOTime currentTime, double speed, double vSafe, double vMin, double vMax) {
302  // keep original speed
303  myOriginalSpeed = speed;
304  // remove leading commands which are no longer valid
305  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
306  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
307  }
308  // do nothing if the time line does not apply for the current time
309  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
310  return speed;
311  }
312  // compute and set new speed
314  mySpeedTimeLine[0].second = speed;
316  }
317  currentTime += DELTA_T;
318  const double td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
319  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
321  speed = MIN2(speed, vSafe);
322  }
324  speed = MIN2(speed, vMax);
325  }
327  speed = MAX2(speed, vMin);
328  }
329  return speed;
330 }
331 
332 
333 double
335  return mySpeedTimeLine.empty() ? -1 : myOriginalSpeed;
336 }
337 
338 
339 int
340 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state) {
341  // remove leading commands which are no longer valid
342  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
343  myLaneTimeLine.erase(myLaneTimeLine.begin());
344  }
345  ChangeRequest changeRequest = REQUEST_NONE;
346  // do nothing if the time line does not apply for the current time
347  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
348  const int destinationLaneIndex = myLaneTimeLine[1].second;
349  if (destinationLaneIndex < (int)currentEdge.getLanes().size()) {
350  if (currentLaneIndex > destinationLaneIndex) {
351  changeRequest = REQUEST_RIGHT;
352  } else if (currentLaneIndex < destinationLaneIndex) {
353  changeRequest = REQUEST_LEFT;
354  } else {
355  changeRequest = REQUEST_HOLD;
356  }
357  }
358  }
359  // check whether the current reason shall be canceled / overridden
360  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
361  // flags for the current reason
362  LaneChangeMode mode = LC_NEVER;
363  if ((state & LCA_STRATEGIC) != 0) {
364  mode = myStrategicLC;
365  } else if ((state & LCA_COOPERATIVE) != 0) {
366  mode = myCooperativeLC;
367  } else if ((state & LCA_SPEEDGAIN) != 0) {
368  mode = mySpeedGainLC;
369  } else if ((state & LCA_KEEPRIGHT) != 0) {
370  mode = myRightDriveLC;
371  } else if ((state & LCA_SUBLANE) != 0) {
372  mode = mySublaneLC;
373  } else if ((state & LCA_TRACI) != 0) {
374  mode = LC_NEVER;
375  } else {
376  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
377  }
378  if (mode == LC_NEVER) {
379  // cancel all lcModel requests
380  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
381  state &= ~LCA_URGENT;
382  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
383  if (
384  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
385  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
386  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
387  // cancel conflicting lcModel request
388  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
389  state &= ~LCA_URGENT;
390  }
391  } else if (mode == LC_ALWAYS) {
392  // ignore any TraCI requests
393  return state;
394  }
395  }
396  // apply traci requests
397  if (changeRequest == REQUEST_NONE) {
398  return state;
399  } else {
400  state |= LCA_TRACI;
401  // security checks
403  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
404  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
405  }
406  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
407  state |= LCA_URGENT;
408  }
409  switch (changeRequest) {
410  case REQUEST_HOLD:
411  return state | LCA_STAY;
412  case REQUEST_LEFT:
413  return state | LCA_LEFT;
414  case REQUEST_RIGHT:
415  return state | LCA_RIGHT;
416  default:
417  throw ProcessError("should not happen");
418  }
419  }
420 }
421 
422 
423 double
425  assert(myLaneTimeLine.size() >= 2);
426  assert(currentTime >= myLaneTimeLine[0].first);
427  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
428 }
429 
430 
431 void
433  myConsiderSafeVelocity = ((speedMode & 1) != 0);
434  myConsiderMaxAcceleration = ((speedMode & 2) != 0);
435  myConsiderMaxDeceleration = ((speedMode & 4) != 0);
436  myRespectJunctionPriority = ((speedMode & 8) != 0);
437  myEmergencyBrakeRedLight = ((speedMode & 16) != 0);
438 }
439 
440 
441 void
443  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
444  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
445  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
446  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
447  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
448  mySublaneLC = (LaneChangeMode)((value & (1024 + 2048)) >> 10);
449 }
450 
451 
452 void
453 MSVehicle::Influencer::setVTDControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
454  myVTDXYPos = xyPos;
455  myVTDLane = l;
456  myVTDPos = pos;
457  myVTDPosLat = posLat;
458  myVTDAngle = angle;
459  myVTDEdgeOffset = edgeOffset;
460  myVTDRoute = route;
461  myLastVTDAccess = t;
462 }
463 
464 
465 bool
468 }
469 
470 
471 bool
473  return myLastVTDAccess >= t - TIME2STEPS(10);
474 }
475 
476 void
478  const bool wasOnRoad = v->isOnRoad();
479  if (v->isOnRoad()) {
482  }
483  if (myVTDRoute.size() != 0) {
484  v->replaceRouteEdges(myVTDRoute, true);
485  }
487  if (myVTDLane != 0 && myVTDPos > myVTDLane->getLength()) {
489  }
490  if (myVTDLane != 0 && fabs(myVTDPosLat) < 0.5 * (myVTDLane->getWidth() + v->getVehicleType().getWidth())) {
492  v->updateBestLanes();
493  if (!wasOnRoad) {
494  v->drawOutsideNetwork(false);
495  }
496  //std::cout << "on road network p=" << myVTDXYPos << " a=" << myVTDAngle << " l=" << Named::getIDSecure(myVTDLane) << " pos=" << myVTDPos << " posLat=" << myVTDPosLat << "\n";
497  } else {
498  if (v->getDeparture() == NOT_YET_DEPARTED) {
499  v->onDepart();
500  }
501  v->drawOutsideNetwork(true);
502  //std::cout << "outside network p=" << myVTDXYPos << " a=" << myVTDAngle << " l=" << Named::getIDSecure(myVTDLane) << "\n";
503  }
504  // ensure that the position is correct (i.e. when the lanePosition is ambiguous at corners)
506  // inverse of GeomHelper::naviDegree
507  v->setAngle(M_PI / 2. - DEG2RAD(myVTDAngle));
508 }
509 
510 
511 double
513  double dist = 0;
514  if (myVTDLane == 0) {
515  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
516  } else {
518  }
519  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
520  return oldSpeed;
521  } else {
522  return DIST2SPEED(dist);
523  }
524 }
525 
526 double
528  double dist = 0;
529  if (myVTDLane == 0) {
530  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
531  } else {
533  }
534  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
535  return 0;
536  } else {
537  return dist;
538  }
539 }
540 
541 
544  if (myRoutingMode == 1) {
546  } else {
547  return MSNet::getInstance()->getRouterTT();
548  }
549 }
550 
551 #endif
552 
553 
554 /* -------------------------------------------------------------------------
555  * MSVehicle-methods
556  * ----------------------------------------------------------------------- */
558  MSVehicleType* type, const double speedFactor) :
559  MSBaseVehicle(pars, route, type, speedFactor),
560  myWaitingTime(0),
562  myTimeLoss(0),
563  myState(0, 0, 0, 0), //
564  myLane(0),
567  myPersonDevice(0),
569  myAcceleration(0),
570  mySignals(0),
571  myAmOnNet(false),
574  myHaveToWaitOnNextLink(false),
575  myAngle(0),
576  myStopDist(std::numeric_limits<double>::max()),
579  myEdgeWeights(0)
580 #ifndef NO_TRACI
581  , myInfluencer(0)
582 #endif
583 {
584  if (!(*myCurrEdge)->isTazConnector()) {
585  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
586  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
587  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
588  }
589  } else {
590  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
591  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
592  }
593  }
594  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
595  throw ProcessError("Departure speed for vehicle '" + pars->id +
596  "' is too high for the vehicle type '" + type->getID() + "'.");
597  }
598  }
601 }
602 
603 
605  delete myEdgeWeights;
606  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
607  (*i)->resetPartialOccupation(this);
608  }
611  // still needed when calling resetPartialOccupation (getShadowLane) and when removing
612  // approach information from parallel links
613  delete myLaneChangeModel;
614  myFurtherLanes.clear();
615  myFurtherLanesPosLat.clear();
616  //
617  if (myType->isVehicleSpecific()) {
619  }
620 #ifndef NO_TRACI
621  delete myInfluencer;
622 #endif
623 }
624 
625 
626 void
630  leaveLane(reason);
631 }
632 
633 
634 // ------------ interaction with the route
635 bool
637  return (myCurrEdge == myRoute->end() - 1
638  && (myStops.empty() || myStops.front().edge != myCurrEdge)
640  && !isRemoteControlled());
641 }
642 
643 
644 bool
645 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset, bool addStops) {
646  const ConstMSEdgeVector& edges = newRoute->getEdges();
647  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
648  if (!onInit && !newRoute->contains(*myCurrEdge)) {
649  return false;
650  }
651 
652  // rebuild in-vehicle route information
653  if (onInit) {
654  myCurrEdge = newRoute->begin();
655  } else {
656  MSRouteIterator newCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);;
657  if (myLane->getEdge().isInternal() && (
658  (newCurrEdge + 1) == edges.end() || (*(newCurrEdge + 1)) != &(myLane->getOutgoingLanes()[0]->getEdge()))) {
659  return false;
660  }
661  myCurrEdge = newCurrEdge;
662  }
663  // check whether the old route may be deleted (is not used by anyone else)
664  newRoute->addReference();
665  myRoute->release();
666  // assign new route
667  myRoute = newRoute;
668  // update arrival definition
670  // save information that the vehicle was rerouted
673  // recheck old stops
674  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
675  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
676  iter = myStops.erase(iter);
677  } else {
678  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
679  ++iter;
680  }
681  }
682  // add new stops
683  if (addStops) {
684  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
685  std::string error;
686  addStop(*i, error);
687  if (error != "") {
688  WRITE_WARNING(error);
689  }
690  }
691  }
692  // update best lanes (after stops were added)
695  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
696  return true;
697 }
698 
699 
700 bool
701 MSVehicle::willPass(const MSEdge* const edge) const {
702  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
703 }
704 
705 
706 int
708  return (int) std::distance(myRoute->begin(), myCurrEdge);
709 }
710 
711 
712 void
714  myCurrEdge = myRoute->begin() + index;
715  // !!! hack
716  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
717 }
718 
719 
720 
723  return _getWeightsStorage();
724 }
725 
726 
729  return _getWeightsStorage();
730 }
731 
732 
735  if (myEdgeWeights == 0) {
737  }
738  return *myEdgeWeights;
739 }
740 
741 
742 // ------------ Interaction with move reminders
743 void
744 MSVehicle::workOnMoveReminders(double oldPos, double newPos, double newSpeed) {
745  // This erasure-idiom works for all stl-sequence-containers
746  // See Meyers: Effective STL, Item 9
747  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
748  // XXX: calling notifyMove with newSpeed seems not the best choice. For the ballistic update, the average speed is calculated and used
749  // although a higher order quadrature-formula might be more adequate.
750  // For the euler case (where the speed is considered constant for each time step) it is conceivable that
751  // the current calculations may lead to systematic errors for large time steps (compared to reality). Refs. #2579
752  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, MAX2(0., newSpeed))) {
753 #ifdef _DEBUG
754  if (myTraceMoveReminders) {
755  traceMoveReminder("notifyMove", rem->first, rem->second, false);
756  }
757 #endif
758  rem = myMoveReminders.erase(rem);
759  } else {
760 #ifdef _DEBUG
761  if (myTraceMoveReminders) {
762  traceMoveReminder("notifyMove", rem->first, rem->second, true);
763  }
764 #endif
765  ++rem;
766  }
767  }
768 }
769 
770 
771 // XXX: consider renaming...
772 void
774  // save the old work reminders, patching the position information
775  // add the information about the new offset to the old lane reminders
776  const double oldLaneLength = myLane->getLength();
777  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
778  rem->second += oldLaneLength;
779 #ifdef _DEBUG
780 // if (rem->first==0) std::cout << "Null reminder (?!)" << std::endl;
781 // std::cout << "Adapted MoveReminder on lane " << ((rem->first->getLane()==0) ? "NULL" : rem->first->getLane()->getID()) <<" position to " << rem->second << std::endl;
782  if (myTraceMoveReminders) {
783  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
784  }
785 #endif
786  }
787  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
788  addReminder(*rem);
789  }
790 }
791 
792 
793 // ------------ Other getter methods
794 double
796  if (myLane == 0) {
797  return 0;
798  }
799  const double lp = getPositionOnLane();
800  const double gp = myLane->interpolateLanePosToGeometryPos(lp);
801  return myLane->getShape().slopeDegreeAtOffset(gp);
802 }
803 
804 
805 Position
806 MSVehicle::getPosition(const double offset) const {
807  if (myLane == 0) {
808  // when called in the context of GUI-Drawing, the simulation step is already incremented
810  return myCachedPosition;
811  } else {
812  return Position::INVALID;
813  }
814  }
815  if (isParking()) {
816  if (myStops.begin()->parkingarea != 0) {
817  return myStops.begin()->parkingarea->getVehiclePosition(*this);
818  } else {
819  // position beside the road
820  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
821  shp.move2side(SUMO_const_laneWidth * (MSNet::getInstance()->lefthand() ? -1 : 1));
823  }
824  }
825  const bool changingLanes = getLaneChangeModel().isChangingLanes();
826  if (offset == 0. && !changingLanes) {
829  }
830  return myCachedPosition;
831  }
833  return result;
834 }
835 
836 
837 Position
840  const std::vector<MSLane*>& bestLanes = getBestLanesContinuation();
841  auto nextBestLane = bestLanes.begin();
842  double pos = myState.myPos;
843  const MSLane* lane = getLane();
844  assert(lane != 0);
845  bool success = true;
846 
847  while (offset > 0) {
848  // take into account lengths along internal lanes
849  while (lane->isInternal() && offset > 0) {
850  if (offset > lane->getLength() - pos) {
851  offset -= lane->getLength() - pos;
852  lane = lane->getLinkCont()[0]->getViaLaneOrLane();
853  pos = 0.;
854  if (lane == 0) {
855  success = false;
856  offset = 0.;
857  }
858  } else {
859  pos += offset;
860  offset = 0;
861  }
862  }
863  // set nextBestLane to next non-internal lane
864  while (nextBestLane != bestLanes.end() && *nextBestLane == 0) {
865  ++nextBestLane;
866  }
867  if (offset > 0) {
868  assert(!lane->isInternal());
869  assert(lane == *nextBestLane);
870  if (offset > lane->getLength() - pos) {
871  offset -= lane->getLength() - pos;
872  ++nextBestLane;
873  assert(nextBestLane == bestLanes.end() || *nextBestLane != 0);
874  if (nextBestLane == bestLanes.end()) {
875  success = false;
876  offset = 0.;
877  } else {
878  MSLink* link = lane->getLinkTo(*nextBestLane);
879  assert(link != 0);
880  lane = link->getViaLaneOrLane();
881  pos = 0.;
882  }
883  } else {
884  pos += offset;
885  offset = 0;
886  }
887  }
888 
889  }
890 
891  if (success) {
893  } else {
894  return Position::INVALID;
895  }
896 }
897 
898 
899 Position
900 MSVehicle::validatePosition(Position result, double offset) const {
901  int furtherIndex = 0;
902  while (result == Position::INVALID) {
903  if (furtherIndex >= (int)myFurtherLanes.size()) {
904  //WRITE_WARNING("Could not compute position for vehicle '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
905  break;
906  }
907  //std::cout << SIMTIME << " veh=" << getID() << " lane=" << myLane->getID() << " pos=" << getPositionOnLane() << " posLat=" << getLateralPositionOnLane() << " offset=" << offset << " result=" << result << " i=" << furtherIndex << " further=" << myFurtherLanes.size() << "\n";
908  result = myFurtherLanes[furtherIndex]->geometryPositionAtOffset(myFurtherLanes[furtherIndex]->getLength() + offset, -getLateralPositionOnLane());
909  furtherIndex++;
910  }
911  return result;
912 }
913 
914 
915 const MSEdge*
917  // too close to the next junction, so avoid an emergency brake here
918  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
920  return *(myCurrEdge + 1);
921  }
922  if (myLane != 0) {
923  return myLane->getNextNormal();
924  }
925  return *myCurrEdge;
926 }
927 
928 void
929 MSVehicle::setAngle(double angle) {
930  myAngle = angle;
931 }
932 
933 
934 double
936  Position p1;
937  const double posLat = -myState.myPosLat; // @todo get rid of the '-'
938  if (isParking()) {
939  if (myStops.begin()->parkingarea != 0) {
940  return myStops.begin()->parkingarea->getVehicleAngle(*this);
941  } else {
943  }
944  }
946  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
948  } else {
949  p1 = getPosition();
950  }
951 
952  Position p2 = getBackPosition();
953  if (p2 == Position::INVALID) {
954  // Handle special case of vehicle's back reaching out of the network
955  if (myFurtherLanes.size() > 0) {
956  p2 = myFurtherLanes.back()->geometryPositionAtOffset(0, -myFurtherLanesPosLat.back());
957  } else {
958  p2 = myLane->geometryPositionAtOffset(0, posLat);
959  }
960  }
961  double result = (p1 != p2 ? p2.angleTo2D(p1) :
964  result += DEG2RAD(getLaneChangeModel().getAngleOffset());
965  }
966 #ifdef DEBUG_FURTHER
967  if (DEBUG_COND) {
968  std::cout << SIMTIME << " computeAngle veh=" << getID() << " p1=" << p1 << " p2=" << p2 << " angle=" << result << "\n";
969  }
970 #endif
971  return result;
972 }
973 
974 
975 const Position
977  const double posLat = -myState.myPosLat; // @todo get rid of the '-'
978  if (myState.myPos >= myType->getLength()) {
979  // vehicle is fully on the new lane
981  } else {
983  // special case where the target lane has no predecessor
984  return myLane->geometryPositionAtOffset(0, posLat);
985  } else {
986 #ifdef DEBUG_FURTHER
987  if (DEBUG_COND) {
988  std::cout << " getBackPosition veh=" << getID() << " myLane=" << myLane->getID() << " further=" << toString(myFurtherLanes) << " myFurtherLanesPosLat=" << toString(myFurtherLanesPosLat) << "\n";
989  }
990 #endif
991  return myFurtherLanes.size() > 0 && !getLaneChangeModel().isChangingLanes()
992  ? myFurtherLanes.back()->geometryPositionAtOffset(getBackPositionOnLane(myFurtherLanes.back()), -myFurtherLanesPosLat.back())
993  : myLane->geometryPositionAtOffset(0, posLat);
994  }
995  }
996 }
997 
998 // ------------
999 bool
1000 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset, bool collision,
1001  MSRouteIterator* searchStart) {
1002  Stop stop;
1003  stop.lane = MSLane::dictionary(stopPar.lane);
1004  if (!stop.lane->allowsVehicleClass(myType->getVehicleClass())) {
1005  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
1006  return false;
1007  }
1008  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
1012  stop.startPos = stopPar.startPos;
1013  stop.endPos = stopPar.endPos;
1014  stop.duration = stopPar.duration;
1015  stop.until = stopPar.until;
1016  stop.timeToBoardNextPerson = 0;
1017  stop.timeToLoadNextContainer = 0;
1018  stop.awaitedPersons = stopPar.awaitedPersons;
1019  stop.awaitedContainers = stopPar.awaitedContainers;
1020  if (stop.until != -1) {
1021  stop.until += untilOffset;
1022  }
1023  stop.triggered = stopPar.triggered;
1024  stop.containerTriggered = stopPar.containerTriggered;
1025  stop.parking = stopPar.parking;
1026  stop.collision = collision;
1027  stop.reached = false;
1028  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
1029  if (stop.busstop != 0) {
1030  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
1031  } else {
1032  errorMsg = "Stop";
1033  }
1034  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
1035  return false;
1036  }
1037  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
1038  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
1039  }
1040  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
1041  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
1042  }
1043  if (stop.parkingarea != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
1044  errorMsg = "Parking area '" + stop.parkingarea->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
1045  }
1046  // if stop is on an internal edge the normal edge before the intersection is used
1047  const MSEdge* stopEdge = stop.lane->getEdge().getNormalBefore();
1048  if (searchStart == 0) {
1049  searchStart = &myCurrEdge;
1050  }
1051  stop.edge = find(*searchStart, myRoute->end(), stopEdge);
1052  MSRouteIterator prevStopEdge = myCurrEdge;
1053  double prevStopPos = myState.myPos;
1054  // where to insert the stop
1055  std::list<Stop>::iterator iter = myStops.begin();
1056  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
1057  if (myStops.size() > 0) {
1058  prevStopEdge = myStops.back().edge;
1059  prevStopPos = myStops.back().endPos;
1060  iter = myStops.end();
1061  stop.edge = find(prevStopEdge, myRoute->end(), stopEdge);
1062  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
1063  stop.edge = find(prevStopEdge + 1, myRoute->end(), stopEdge);
1064  }
1065  }
1066  } else {
1067  if (stopPar.index == STOP_INDEX_FIT) {
1068  while (iter != myStops.end() && (iter->edge < stop.edge ||
1069  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
1070  prevStopEdge = iter->edge;
1071  prevStopPos = iter->endPos;
1072  ++iter;
1073  }
1074  } else {
1075  int index = stopPar.index;
1076  while (index > 0) {
1077  prevStopEdge = iter->edge;
1078  prevStopPos = iter->endPos;
1079  ++iter;
1080  --index;
1081  }
1082  stop.edge = find(prevStopEdge, myRoute->end(), stopEdge);
1083  }
1084  }
1085  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
1086  (prevStopEdge == stop.edge && prevStopPos > stop.endPos && !collision)
1087  || (stop.lane->getEdge().isInternal() && stop.lane->getNextNormal() != *(stop.edge + 1))) {
1088  if (stop.edge != myRoute->end()) {
1089  // check if the edge occurs again later in the route
1090  MSRouteIterator next = stop.edge + 1;
1091  return addStop(stopPar, errorMsg, untilOffset, collision, &next);
1092  }
1093  if (stop.busstop != 0) {
1094  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
1095  } else {
1096  errorMsg = "Stop";
1097  }
1098  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
1099  return false;
1100  }
1101  // David.C:
1102  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
1103  const double endPosOffset = stop.lane->getEdge().isInternal() ? (*stop.edge)->getLength() : 0;
1104  if (collision) {
1105  assert(myCurrEdge == stop.edge);
1106  myState.myPos = stop.endPos;
1107  myState.mySpeed = 0;
1108  } else if (myCurrEdge == stop.edge && myState.myPos > stop.endPos + endPosOffset - getCarFollowModel().brakeGap(myState.mySpeed)) {
1109  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
1110  return false;
1111  }
1112  if (!hasDeparted() && myCurrEdge == stop.edge) {
1113  double pos = -1;
1115  pos = myParameter->departPos;
1116  if (pos < 0.) {
1117  pos += (*myCurrEdge)->getLength();
1118  }
1119  }
1121  pos = MIN2(static_cast<double>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
1122  }
1123  if (pos > stop.endPos + endPosOffset) {
1124  if (stop.edge != myRoute->end()) {
1125  // check if the edge occurs again later in the route
1126  MSRouteIterator next = stop.edge + 1;
1127  return addStop(stopPar, errorMsg, untilOffset, collision, &next);
1128  }
1129  if (stop.busstop != 0) {
1130  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
1131  } else {
1132  errorMsg = "Stop";
1133  }
1134  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
1135  return false;
1136  }
1137  }
1138  if (iter != myStops.begin()) {
1139  std::list<Stop>::iterator iter2 = iter;
1140  iter2--;
1141  if (stop.until >= 0 && iter2->until > stop.until) {
1142  if (stop.busstop != 0) {
1143  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
1144  } else {
1145  errorMsg = "Stop";
1146  }
1147  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
1148  }
1149  }
1150  myStops.insert(iter, stop);
1151  return true;
1152 }
1153 
1154 
1155 bool
1156 MSVehicle::replaceParkingArea(MSParkingArea* parkingArea, std::string& errorMsg) {
1157  // Check if there is a parking area to be replaced
1158  assert(parkingArea != 0);
1159  if (myStops.empty()) {
1160  errorMsg = "Vehicle '" + myParameter->id + "' has no stops.";
1161  return false;
1162  }
1164  Stop stop = myStops.front();
1165  if (stop.reached) {
1166  errorMsg = "current stop already reached";
1167  return false;
1168  }
1169  if (stop.parkingarea == 0) {
1170  errorMsg = "current stop is not a parkingArea";
1171  return false;
1172  }
1173  if (stop.parkingarea == parkingArea) {
1174  errorMsg = "current stop is the same as the new parking area";
1175  return false;
1176  }
1177  stopPar.lane = parkingArea->getLane().getID();
1178 
1179  // merge duplicated stops equals to parking area
1180  int removeStops = 0;
1181  SUMOTime duration = 0;
1182 
1183  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1184  if (duration == 0) {
1185  duration = iter->duration;
1186  ++removeStops;
1187  } else {
1188  if (iter->parkingarea != 0 && iter->parkingarea == parkingArea) {
1189  duration += iter->duration;
1190  ++removeStops;
1191  } else {
1192  break;
1193  }
1194  }
1195  }
1196 
1197  stopPar.index = 0;
1198  stopPar.busstop = "";
1199  stopPar.chargingStation = "";
1200  stopPar.containerstop = "";
1201  stopPar.parkingarea = parkingArea->getID();
1202  stopPar.startPos = parkingArea->getBeginLanePosition();
1203  stopPar.endPos = parkingArea->getEndLanePosition();
1204  stopPar.duration = duration;
1205  stopPar.until = stop.until;
1206  stopPar.awaitedPersons = stop.awaitedPersons;
1207  stopPar.awaitedContainers = stop.awaitedContainers;
1208  stopPar.triggered = stop.triggered;
1209  stopPar.containerTriggered = stop.containerTriggered;
1210  stopPar.parking = stop.parking;
1211 
1212  // remove stops equals to parking area
1213  while (removeStops > 0) {
1214  myStops.pop_front();
1215  --removeStops;
1216  }
1217  const bool result = addStop(stopPar, errorMsg);
1218  if (myLane != 0) {
1219  updateBestLanes(true);
1220  }
1221  return result;
1222 }
1223 
1224 
1227  MSParkingArea* nextParkingArea = 0;
1228  if (!myStops.empty()) {
1230  Stop stop = myStops.front();
1231  if (!stop.reached && stop.parkingarea != 0) {
1232  nextParkingArea = stop.parkingarea;
1233  }
1234  }
1235  return nextParkingArea;
1236 }
1237 
1238 
1239 bool
1241  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
1242 }
1243 
1244 bool
1246  return isStopped() && myStops.front().lane == myLane;
1247 }
1248 
1249 bool
1250 MSVehicle::keepStopping(bool afterProcessing) const {
1251  if (isStopped()) {
1252  // after calling processNextStop, DELTA_T has already been subtracted from the duration
1253  return myStops.front().duration + (afterProcessing ? DELTA_T : 0) > 0 || isStoppedTriggered() || myStops.front().collision;
1254  } else {
1255  return false;
1256  }
1257 }
1258 
1259 SUMOTime
1261  return (myStops.empty() || !myStops.front().collision) ? myCollisionImmunity : MAX2((SUMOTime)0, myStops.front().duration);
1262 }
1263 
1264 
1265 bool
1267  return isStopped() && myStops.begin()->parking;
1268 }
1269 
1270 
1271 bool
1273  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
1274 }
1275 
1276 
1277 bool
1278 MSVehicle::isStoppedInRange(double pos) const {
1279  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
1280 }
1281 
1282 
1283 double
1284 MSVehicle::processNextStop(double currentVelocity) {
1285  if (myStops.empty()) {
1286  // no stops; pass
1287  return currentVelocity;
1288  }
1289 
1290 #ifdef DEBUG_STOPS
1291  if (DEBUG_COND) {
1292  std::cout << "\nPROCESS_NEXT_STOP\n" << SIMTIME << " vehicle '" << getID() << "'" << std::endl;
1293  }
1294 #endif
1295 
1296  Stop& stop = myStops.front();
1297  if (stop.reached) {
1298 
1299 #ifdef DEBUG_STOPS
1300  if (DEBUG_COND) {
1301  std::cout << SIMTIME << " vehicle '" << getID() << "' reached stop." << std::endl;
1302  }
1303 #endif
1304  // ok, we have already reached the next stop
1305  // any waiting persons may board now
1306  MSNet* const net = MSNet::getInstance();
1307  bool boarded = net->hasPersons() && net->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
1308  boarded &= stop.awaitedPersons.size() == 0;
1309  // load containers
1310  bool loaded = net->hasContainers() && net->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
1311  loaded &= stop.awaitedContainers.size() == 0;
1312  if (boarded) {
1313  if (stop.busstop != 0) {
1314  const std::vector<MSTransportable*>& persons = myPersonDevice->getTransportables();
1315  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
1316  stop.busstop->removeTransportable(*i);
1317  }
1318  }
1319  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
1320  stop.triggered = false;
1324 #ifdef DEBUG_STOPS
1325  if (DEBUG_COND) {
1326  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for person." << std::endl;
1327  }
1328 #endif
1329  }
1330  }
1331  if (loaded) {
1332  if (stop.containerstop != 0) {
1333  const std::vector<MSTransportable*>& containers = myContainerDevice->getTransportables();
1334  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
1336  }
1337  }
1338  // the triggering condition has been fulfilled
1339  stop.containerTriggered = false;
1343 #ifdef DEBUG_STOPS
1344  if (DEBUG_COND) {
1345  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for container." << std::endl;
1346  }
1347 #endif
1348  }
1349  }
1350  if (!keepStopping() && isOnRoad()) {
1351 #ifdef DEBUG_STOPS
1352  if (DEBUG_COND) {
1353  std::cout << SIMTIME << " vehicle '" << getID() << "' resumes from stopping." << std::endl;
1354  }
1355 #endif
1357  } else {
1359  if (getVehicleType().getPersonCapacity() == getPersonNumber()) {
1360  WRITE_WARNING("Vehicle '" + getID() + "' ignores triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1361  stop.triggered = false;
1362  }
1363  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1366 #ifdef DEBUG_STOPS
1367  if (DEBUG_COND) {
1368  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for person." << std::endl;
1369  }
1370 #endif
1371  }
1373  if (getVehicleType().getContainerCapacity() == getContainerNumber()) {
1374  WRITE_WARNING("Vehicle '" + getID() + "' ignores container triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1375  stop.containerTriggered = false;
1376  }
1377  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1380 #ifdef DEBUG_STOPS
1381  if (DEBUG_COND) {
1382  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for container." << std::endl;
1383  }
1384 #endif
1385  }
1386  // we have to wait some more time
1387  stop.duration -= DELTA_T;
1388 
1390  // euler
1391  return 0;
1392  } else {
1393  // ballistic:
1394  return getCarFollowModel().stopSpeed(this, getSpeed(), stop.getEndPos(*this) - myState.pos());
1395  }
1396  }
1397  } else {
1398 
1399 #ifdef DEBUG_STOPS
1400  if (DEBUG_COND) {
1401  std::cout << SIMTIME << " vehicle '" << getID() << "' hasn't reached next stop." << std::endl;
1402  }
1403 #endif
1404 
1405  // is the next stop on the current lane?
1406  if (stop.edge == myCurrEdge) {
1407  // get the stopping position
1408  double endPos = stop.endPos;
1409  bool useStoppingPlace = false;
1410  bool fitsOnStoppingPlace = true;
1411  if (stop.busstop != 0) {
1412  useStoppingPlace = true;
1413  // on bus stops, we have to wait for free place if they are in use...
1414  endPos = stop.busstop->getLastFreePos(*this);
1415  // at least half the bus has to fit on non-empty bus stops
1416  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
1417  fitsOnStoppingPlace = false;
1418  }
1419  }
1420  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
1421  if (stop.containerstop != 0) {
1422  useStoppingPlace = true;
1423  // on container stops, we have to wait for free place if they are in use...
1424  endPos = stop.containerstop->getLastFreePos(*this);
1425  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
1426  fitsOnStoppingPlace = false;
1427  }
1428  }
1429  // if the stop is a parking area we check if there is a free position on the area
1430  if (stop.parkingarea != 0) {
1431  endPos = stop.parkingarea->getLastFreePos(*this);
1432  if (stop.parkingarea->getOccupancy() == stop.parkingarea->getCapacity()) {
1433  fitsOnStoppingPlace = false;
1434  // trigger potential parkingZoneReroute
1435  for (std::vector< MSMoveReminder* >::const_iterator rem = myLane->getMoveReminders().begin(); rem != myLane->getMoveReminders().end(); ++rem) {
1436  addReminder(*rem);
1437  }
1438  MSParkingArea* oldParkingArea = stop.parkingarea;
1440  if (myStops.empty() || myStops.front().parkingarea != oldParkingArea) {
1441  // rerouted, keep driving
1442  return currentVelocity;
1443  }
1444  }
1445  }
1446  if (stop.lane->getEdge().isInternal() && &myLane->getEdge() != &stop.lane->getEdge()) {
1447  // endPos is on subsequent edge
1448  endPos += myLane->getLength();
1449  }
1450 
1451  const double reachedThreshold = (useStoppingPlace ? endPos - STOPPING_PLACE_OFFSET : stop.startPos) - NUMERICAL_EPS;
1452  if (myState.pos() >= reachedThreshold && fitsOnStoppingPlace && currentVelocity <= SUMO_const_haltingSpeed && myLane == stop.lane) {
1453  // ok, we may stop (have reached the stop)
1454  stop.reached = true;
1455  if (MSStopOut::active()) {
1457  }
1458  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
1460  // compute stopping time
1461  if (stop.until >= 0) {
1462  if (stop.duration == -1) {
1464  } else {
1466  }
1467  }
1468  if (stop.busstop != 0) {
1469  // let the bus stop know the vehicle
1470  stop.busstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
1471  }
1472  if (stop.containerstop != 0) {
1473  // let the container stop know the vehicle
1475  }
1476  if (stop.parkingarea != 0) {
1477  // let the parking area know the vehicle
1479  }
1480  }
1481  // decelerate
1483  // euler
1484  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos() + NUMERICAL_EPS);
1485  } else {
1486  // ballistic
1487  return getCarFollowModel().stopSpeed(this, myState.mySpeed, endPos - myState.myPos);
1488  }
1489  }
1490  }
1491  return currentVelocity;
1492 }
1493 
1494 
1495 const ConstMSEdgeVector
1497  ConstMSEdgeVector result;
1498  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1499  result.push_back(*iter->edge);
1500  }
1501  return result;
1502 }
1503 
1504 
1505 void
1506 MSVehicle::planMove(const SUMOTime t, const MSLeaderInfo& ahead, const double lengthsInFront) {
1507 
1508 #ifdef DEBUG_PLAN_MOVE
1509  if (DEBUG_COND) {
1510  std::cout
1511  << "\nPLAN_MOVE\n"
1512  << STEPS2TIME(t)
1513  << " veh=" << getID()
1514  << " lane=" << myLane->getID()
1515  << " pos=" << getPositionOnLane()
1516  << " posLat=" << getLateralPositionOnLane()
1517  << " speed=" << getSpeed()
1518  << "\n";
1519  }
1520 #endif
1521  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
1522 #ifdef DEBUG_PLAN_MOVE
1523  if (DEBUG_COND) {
1524  DriveItemVector::iterator i;
1525  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1526  std::cout
1527  << " vPass=" << (*i).myVLinkPass
1528  << " vWait=" << (*i).myVLinkWait
1529  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1530  << " request=" << (*i).mySetRequest
1531  << "\n";
1532  }
1533  }
1534 #endif
1535  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
1536 #ifdef DEBUG_PLAN_MOVE
1537  if (DEBUG_COND) {
1538  std::cout << " after checkRewindLinkLanes\n";
1539  DriveItemVector::iterator i;
1540  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1541  std::cout
1542  << " vPass=" << (*i).myVLinkPass
1543  << " vWait=" << (*i).myVLinkWait
1544  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1545  << " request=" << (*i).mySetRequest
1546  << " atime=" << (*i).myArrivalTime
1547  << " atimeB=" << (*i).myArrivalTimeBraking
1548  << "\n";
1549  }
1550  }
1551 #endif
1553 }
1554 
1555 
1556 void
1558 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1559  if (gDebugSelectedVehicle == getID()) {
1560  int bla = 0;
1561  }
1562 #endif
1563 
1564  // remove information about approaching links, will be reset later in this step
1566  lfLinks.clear();
1567  myStopDist = std::numeric_limits<double>::max();
1568  //
1569  const MSCFModel& cfModel = getCarFollowModel();
1570  const double vehicleLength = getVehicleType().getLength();
1571  const double maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
1572  const bool opposite = getLaneChangeModel().isOpposite();
1573  double laneMaxV = myLane->getVehicleMaxSpeed(this);
1574  // v is the initial maximum velocity of this vehicle in this step
1575  double v = MIN2(maxV, laneMaxV);
1576 #ifndef NO_TRACI
1577  if (myInfluencer != 0) {
1578  //const double vMin = MAX2(0., cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1579  const double vMin = MAX2(0., cfModel.minNextSpeed(myState.mySpeed, this));
1580  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
1581  }
1582 #endif
1583  // all links within dist are taken into account (potentially)
1584  // the distance already "seen"; in the following always up to the end of the current "lane"
1585  const double dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1586 
1587  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
1588 #ifdef DEBUG_PLAN_MOVE
1589  if (DEBUG_COND) {
1590  std::cout << " bestLaneConts=" << toString(bestLaneConts) << "\n";
1591  }
1592 #endif
1593  assert(bestLaneConts.size() > 0);
1594  bool hadNonInternal = false;
1595  double seen = opposite ? myState.myPos : myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
1596  double seenNonInternal = 0;
1597  double vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(seen, v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1598  int view = 0;
1599  DriveProcessItem* lastLink = 0;
1600  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
1601  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1602  const MSLane* lane = opposite ? myLane->getOpposite() : myLane;
1603  assert(lane != 0);
1604  const MSLane* leaderLane = myLane;
1605 #ifdef _MSC_VER
1606 #pragma warning(push)
1607 #pragma warning(disable: 4127) // do not warn about constant conditional expression
1608 #endif
1609  while (true) {
1610 #ifdef _MSC_VER
1611 #pragma warning(pop)
1612 #endif
1613  // check leader on lane
1614  // leader is given for the first edge only
1615  if (opposite &&
1616  (leaderLane->getVehicleNumber() > 1
1617  || (leaderLane != myLane && leaderLane->getVehicleNumber() > 0))) {
1618  // find opposite-driving leader that must be respected on the currently looked at lane
1619  // XXX make sure to look no further than leaderLane
1620  CLeaderDist leader = leaderLane->getOppositeLeader(this, getPositionOnLane(), true);
1621  ahead.clear();
1622  if (leader.first != 0 && leader.first->getLane() == leaderLane && leader.first->getLaneChangeModel().isOpposite()) {
1623  ahead.addLeader(leader.first, true);
1624  }
1625  }
1626  adaptToLeaders(ahead, 0, seen, lastLink, leaderLane, v, vLinkPass);
1627 #ifdef DEBUG_PLAN_MOVE
1628  if (DEBUG_COND) {
1629  std::cout << "\nv = " << v << "\n";
1630 
1631  }
1632 #endif
1633  // XXX efficiently adapt to shadow leaders using neighAhead by iteration over the whole edge in parallel (lanechanger-style)
1634  if (getLaneChangeModel().getShadowLane() != 0) {
1635  // also slow down for leaders on the shadowLane relative to the current lane
1636  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1637  if (shadowLane != 0) {
1638  const double latOffset = getLane()->getRightSideOnEdge() - getLaneChangeModel().getShadowLane()->getRightSideOnEdge();
1639  adaptToLeaders(shadowLane->getLastVehicleInformation(this, latOffset, lane->getLength() - seen),
1640  latOffset,
1641  seen, lastLink, shadowLane, v, vLinkPass);
1642  }
1643  }
1644  // adapt to pedestrians on the same lane
1645  if (lane->getEdge().getPersons().size() > 0 && MSPModel::getModel()->hasPedestrians(lane)) {
1646  const double relativePos = lane->getLength() - seen;
1647 #ifdef DEBUG_PLAN_MOVE
1648  if (DEBUG_COND) {
1649  std::cout << SIMTIME << " adapt to pedestrians on lane=" << lane->getID() << " relPos=" << relativePos << "\n";
1650  }
1651 #endif
1652  PersonDist leader = MSPModel::getModel()->nextBlocking(lane, relativePos,
1654  if (leader.first != 0) {
1655  const double stopSpeed = cfModel.stopSpeed(this, getSpeed(), leader.second - getVehicleType().getMinGap());
1656  v = MIN2(v, stopSpeed);
1657 #ifdef DEBUG_PLAN_MOVE
1658  if (DEBUG_COND) {
1659  std::cout << SIMTIME << " pedLeader=" << leader.first->getID() << " dist=" << leader.second << " v=" << v << "\n";
1660  }
1661 #endif
1662  }
1663  }
1664 
1665  // process stops
1666  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge() && !myStops.begin()->reached
1667  // ignore stops that occur later in a looped route
1668  && myStops.front().edge == myCurrEdge + view) {
1669  // we are approaching a stop on the edge; must not drive further
1670  const Stop& stop = *myStops.begin();
1671  const double endPos = stop.getEndPos(*this) + NUMERICAL_EPS;
1672  myStopDist = seen + endPos - lane->getLength();
1673  const double stopSpeed = cfModel.stopSpeed(this, getSpeed(), myStopDist);
1674  if (lastLink != 0) {
1675  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1676  }
1677  v = MIN2(v, stopSpeed);
1678  lfLinks.push_back(DriveProcessItem(v, myStopDist));
1679 
1680 #ifdef DEBUG_PLAN_MOVE
1681  if (DEBUG_COND) {
1682  std::cout << "\n" << SIMTIME << " next stop: distance = " << myStopDist << " requires stopSpeed = " << stopSpeed << "\n";
1683 
1684  }
1685 #endif
1686 
1687  break;
1688  }
1689 
1690  // move to next lane
1691  // get the next link used
1692  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1693  // check whether the vehicle is on its final edge
1694  if (myCurrEdge + view + 1 == myRoute->end()) {
1695  const double arrivalSpeed = (myParameter->arrivalSpeedProcedure == ARRIVAL_SPEED_GIVEN ?
1696  myParameter->arrivalSpeed : laneMaxV);
1697  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1698  const double distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1699  const double va = MAX2(NUMERICAL_EPS, cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed));
1700  v = MIN2(v, va);
1701  if (lastLink != 0) {
1702  lastLink->adaptLeaveSpeed(va);
1703  }
1704  lfLinks.push_back(DriveProcessItem(v, seen, lane->getEdge().isFringe() ? 1000 : 0));
1705  break;
1706  }
1707  // check whether the lane or the shadowLane is a dead end (allow some leeway on intersections)
1708  if (lane->isLinkEnd(link) ||
1709  ((*link)->getViaLane() == 0
1711  // do not get stuck on narrow edges
1712  && getVehicleType().getWidth() <= lane->getEdge().getWidth()
1713  // this is the exit link of a junction. The normal edge should support the shadow
1714  && ((getLaneChangeModel().getShadowLane((*link)->getLane()) == 0)
1715  // the internal lane after an internal junction has no parallel lane. make sure there is no shadow before continuing
1716  || (lane->getEdge().isInternal() && lane->getIncomingLanes()[0].lane->getEdge().isInternal()))
1717  // ignore situations where the shadow lane is part of a double-connection with the current lane
1718  && (getLaneChangeModel().getShadowLane() == 0
1719  || getLaneChangeModel().getShadowLane()->getLinkCont().size() == 0
1720  || getLaneChangeModel().getShadowLane()->getLinkCont().front()->getLane() != (*link)->getLane())
1721  )) {
1722  double va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1723  if (lastLink != 0) {
1724  lastLink->adaptLeaveSpeed(va);
1725  }
1726  if (getLaneChangeModel().getCommittedSpeed() > 0) {
1727  v = MIN2(getLaneChangeModel().getCommittedSpeed(), v);
1728  } else {
1729  v = MIN2(va, v);
1730  }
1731 #ifdef DEBUG_PLAN_MOVE
1732  if (DEBUG_COND) {
1733  std::cout << " braking for link end: overlap=" << getLateralOverlap() << " va=" << va << " committed=" << getLaneChangeModel().getCommittedSpeed() << " v=" << v << "\n";
1734 
1735  }
1736 #endif
1737  if (lane->isLinkEnd(link)) {
1738  lfLinks.push_back(DriveProcessItem(v, seen));
1739  break;
1740  }
1741  }
1742  const bool yellowOrRed = (*link)->haveRed() || (*link)->haveYellow();
1743  // We distinguish 3 cases when determining the point at which a vehicle stops:
1744  // - links that require stopping: here the vehicle needs to stop close to the stop line
1745  // to ensure it gets onto the junction in the next step. Otherwise the vehicle would 'forget'
1746  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1747  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1748  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1749  // to minimize the time window for passing the junction. If the
1750  // vehicle 'decides' to accelerate and cannot enter the junction in
1751  // the next step, new foes may appear and cause a collision (see #1096)
1752  // - major links: stopping point is irrelevant
1753  const double laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1754  const double stopDist = MAX2(0., seen - laneStopOffset);
1755  // check whether we need to slow down in order to finish a continuous lane change
1756  if (getLaneChangeModel().isChangingLanes()) {
1757  if ( // slow down to finish lane change before a turn lane
1758  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1759  // slow down to finish lane change before the shadow lane ends
1760  (getLaneChangeModel().getShadowLane() != 0 &&
1761  (*link)->getViaLaneOrLane()->getParallelLane(getLaneChangeModel().getShadowDirection()) == 0)) {
1762  // XXX maybe this is too harsh. Vehicles could cut some corners here
1763  const double timeRemaining = STEPS2TIME(getLaneChangeModel().remainingTime());
1764  assert(timeRemaining != 0); // we seem to suppose that isChangingLanes() implies this (Leo)
1765  // XXX: Euler-logic (#860), but I couldn't identify problems from this yet (Leo). Refs. #2575
1766  const double va = MAX2(0., (seen - POSITION_EPS) / timeRemaining);
1767 #ifdef DEBUG_PLAN_MOVE
1768  if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " slowing down to finish continuous change before"
1769  << " link=" << (*link)->getViaLaneOrLane()->getID()
1770  << " timeRemaining=" << timeRemaining
1771  << " v=" << v
1772  << " va=" << va
1773  << "\n";
1774 #endif
1775  v = MIN2(va, v);
1776  }
1777  }
1778 
1779  // - always issue a request to leave the intersection we are currently on
1780  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == 0;
1781  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
1782  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == 0;
1783  // - even if red, if we cannot break we should issue a request
1784  bool setRequest = (v > 0 && !abortRequestAfterMinor) || (leavingCurrentIntersection);
1785 
1786  double vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1787  const double brakeDist = cfModel.brakeGap(myState.mySpeed, cfModel.getMaxDecel(), 0.);
1788  const bool canBrake = seen >= brakeDist;
1789 #ifdef DEBUG_PLAN_MOVE
1791  if (DEBUG_COND) std::cout
1792  << " stopDist=" << stopDist
1793  << " vLinkWait=" << vLinkWait
1794  << " brakeDist=" << brakeDist
1795  << "\n";
1796 #endif
1797  if (yellowOrRed && canBrake && !ignoreRed(*link, canBrake)) {
1798  // the vehicle is able to brake in front of a yellow/red traffic light
1799  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1800  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1801  break;
1802  }
1803 
1804  if (ignoreRed(*link, canBrake) && STEPS2TIME(t - (*link)->getLastStateChange()) > 2) {
1805  // restrict speed when ignoring a red light
1806  const double redSpeed = MIN2(v, getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_DRIVE_RED_SPEED, v));
1807  const double va = MAX2(redSpeed, cfModel.freeSpeed(this, getSpeed(), seen, redSpeed));
1808  v = MIN2(va, v);
1809 #ifdef DEBUG_EXEC_MOVE
1810  if (DEBUG_COND) std::cout
1811  << " ignoreRed spent=" << STEPS2TIME(t - (*link)->getLastStateChange())
1812  << " redSpeed=" << redSpeed
1813  << " va=" << va
1814  << " v=" << v
1815  << "\n";
1816 #endif
1817  }
1818 
1820  // we want to pass the link but need to check for foes on internal lanes
1821  checkLinkLeader(*link, lane, seen, lastLink, v, vLinkPass, vLinkWait, setRequest);
1822  if (getLaneChangeModel().getShadowLane() != 0) {
1823  MSLink* parallelLink = (*link)->getParallelLink(getLaneChangeModel().getShadowDirection());
1824  if (parallelLink != 0) {
1825  checkLinkLeader(parallelLink, lane, seen, lastLink, v, vLinkPass, vLinkWait, setRequest, true);
1826  }
1827  }
1828  }
1829 
1830  if (lastLink != 0) {
1831  lastLink->adaptLeaveSpeed(laneMaxV);
1832  }
1833  double arrivalSpeed = vLinkPass;
1834  // vehicles should decelerate when approaching a minor link
1835  // - unless they are close enough to have clear visibility of all relevant foe lanes and may start to accelerate again
1836  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1837 
1838  // whether the vehicle/driver is close enough to the link to see all possible foes #2123
1839  double visibilityDistance = (*link)->getFoeVisibilityDistance();
1840  double determinedFoePresence = seen < visibilityDistance;
1841 // // VARIANT: account for time needed to recognize whether relevant vehicles are on the foe lanes. (Leo)
1842 // double foeRecognitionTime = 0.0;
1843 // double determinedFoePresence = seen < visibilityDistance - myState.mySpeed*foeRecognitionTime;
1844 
1845 #ifdef DEBUG_PLAN_MOVE
1846  if (DEBUG_COND) {
1847  std::cout << " approaching link=" << (*link)->getViaLaneOrLane()->getID() << " prio=" << (*link)->havePriority() << " seen=" << seen << " visibilityDistance=" << visibilityDistance << " brakeDist=" << brakeDist << "\n";
1848  }
1849 #endif
1850 
1851  if (!(*link)->havePriority() && !determinedFoePresence && brakeDist < seen && !(*link)->lastWasContMajor()) {
1852  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1853  double maxSpeedAtVisibilityDist = cfModel.maximumSafeStopSpeed(visibilityDistance, myState.mySpeed, false, 0.);
1854  // XXX: estimateSpeedAfterDistance does not use euler-logic (thus returns a lower value than possible here...)
1855  double maxArrivalSpeed = cfModel.estimateSpeedAfterDistance(visibilityDistance, maxSpeedAtVisibilityDist, cfModel.getMaxAccel());
1856  arrivalSpeed = MIN2(vLinkPass, maxArrivalSpeed);
1857  slowedDownForMinor = true;
1858 #ifdef DEBUG_PLAN_MOVE
1859  if (DEBUG_COND) {
1860  std::cout << " slowedDownForMinor maxArrivalSpeed=" << maxArrivalSpeed << " arrivalSpeed=" << arrivalSpeed << "\n";
1861  }
1862 #endif
1863  }
1864 
1865  SUMOTime arrivalTime;
1867  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1868  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1869  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1870  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, v, arrivalSpeed);
1871  } else {
1872  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, myState.mySpeed, arrivalSpeed);
1873  }
1874 
1875  // compute arrival speed and arrival time if vehicle starts braking now
1876  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1877  double arrivalSpeedBraking = 0;
1878  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1879  if (seen < cfModel.brakeGap(v)) { // XXX: should this use the current speed (at least for the ballistic case)? (Leo) Refs. #2575
1880  // vehicle cannot come to a complete stop in time
1882  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeedEuler(seen, v);
1883  // due to discrete/continuous mismatch (when using Euler update) we have to ensure that braking actually helps
1884  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1885  } else {
1886  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeed(seen, myState.mySpeed);
1887  }
1888  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1889  }
1890  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1891  arrivalTime, arrivalSpeed,
1892  arrivalTimeBraking, arrivalSpeedBraking,
1893  seen,
1894  estimateLeaveSpeed(*link, arrivalSpeed)));
1895  if ((*link)->getViaLane() == 0) {
1896  hadNonInternal = true;
1897  ++view;
1898  }
1899  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1900  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD) {
1901  break;
1902  }
1903  // get the following lane
1904  lane = (*link)->getViaLaneOrLane();
1905  laneMaxV = lane->getVehicleMaxSpeed(this);
1906  // the link was passed
1907  // compute the velocity to use when the link is not blocked by other vehicles
1908  // the vehicle shall be not faster when reaching the next lane than allowed
1909  const double va = cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV);
1910  v = MIN2(va, v);
1911  seenNonInternal += lane->getEdge().isInternal() ? 0 : lane->getLength();
1912  // do not restrict results to the current vehicle to allow caching for the current time step
1913  leaderLane = opposite ? lane->getOpposite() : lane;
1914  if (leaderLane == 0) {
1915  break;
1916  }
1917  ahead = opposite ? MSLeaderInfo(leaderLane) : leaderLane->getLastVehicleInformation(0, 0);
1918  seen += lane->getLength();
1919  vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(lane->getLength(), v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1920  lastLink = &lfLinks.back();
1921  }
1922 
1923 //#ifdef DEBUG_PLAN_MOVE
1924 // if(DEBUG_COND){
1925 // std::cout << "planMoveInternal found safe speed v = " << v << std::endl;
1926 // }
1927 //#endif
1928 
1929 }
1930 
1931 
1932 void
1933 MSVehicle::adaptToLeaders(const MSLeaderInfo& ahead, double latOffset,
1934  const double seen, DriveProcessItem* const lastLink,
1935  const MSLane* const lane, double& v, double& vLinkPass) const {
1936  int rightmost;
1937  int leftmost;
1938  ahead.getSubLanes(this, latOffset, rightmost, leftmost);
1939 #ifdef DEBUG_PLAN_MOVE
1940  if (DEBUG_COND) std::cout << SIMTIME
1941  << "\nADAPT_TO_LEADERS\nveh=" << getID()
1942  << " lane=" << lane->getID()
1943  << " rm=" << rightmost
1944  << " lm=" << leftmost
1945  << " ahead=" << ahead.toString()
1946  << "\n";
1947 #endif
1948  /*
1949  if (getLaneChangeModel().getCommittedSpeed() > 0) {
1950  v = MIN2(v, getLaneChangeModel().getCommittedSpeed());
1951  vLinkPass = MIN2(vLinkPass, getLaneChangeModel().getCommittedSpeed());
1952  #ifdef DEBUG_PLAN_MOVE
1953  if (DEBUG_COND) std::cout << " hasCommitted=" << getLaneChangeModel().getCommittedSpeed() << "\n";
1954  #endif
1955  return;
1956  }
1957  */
1958  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
1959  const MSVehicle* pred = ahead[sublane];
1960  if (pred != 0) {
1961  // @todo avoid multiple adaptations to the same leader
1962  const double predBack = pred->getBackPositionOnLane(lane);
1963  const double gap = (lastLink == 0
1964  ? predBack - myState.myPos - getVehicleType().getMinGap()
1965  : predBack + seen - lane->getLength() - getVehicleType().getMinGap());
1966 #ifdef DEBUG_PLAN_MOVE
1967  if (DEBUG_COND) {
1968  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";
1969  }
1970 #endif
1971  adaptToLeader(std::make_pair(pred, gap), seen, lastLink, lane, v, vLinkPass);
1972  }
1973  }
1974 }
1975 
1976 
1977 void
1978 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, double> leaderInfo,
1979  const double seen, DriveProcessItem* const lastLink,
1980  const MSLane* const lane, double& v, double& vLinkPass,
1981  double distToCrossing) const {
1982  if (leaderInfo.first != 0) {
1983  const double vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1984  if (lastLink != 0) {
1985  lastLink->adaptLeaveSpeed(vsafeLeader);
1986  }
1987  v = MIN2(v, vsafeLeader);
1988  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1989 
1990 #ifdef DEBUG_PLAN_MOVE
1991  if (DEBUG_COND) std::cout
1992  << SIMTIME
1993  //std::cout << std::setprecision(10);
1994  << " veh=" << getID()
1995  << " lead=" << leaderInfo.first->getID()
1996  << " leadSpeed=" << leaderInfo.first->getSpeed()
1997  << " gap=" << leaderInfo.second
1998  << " leadLane=" << leaderInfo.first->getLane()->getID()
1999  << " predPos=" << leaderInfo.first->getPositionOnLane()
2000  << " seen=" << seen
2001  << " lane=" << lane->getID()
2002  << " myLane=" << myLane->getID()
2003  << " dTC=" << distToCrossing
2004  << " v=" << v
2005  << " vSafeLeader=" << vsafeLeader
2006  << " vLinkPass=" << vLinkPass
2007  << "\n";
2008 #endif
2009  }
2010 }
2011 
2012 
2013 void
2014 MSVehicle::checkLinkLeader(const MSLink* link, const MSLane* lane, double seen,
2015  DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest,
2016  bool isShadowLink) const {
2017  const MSLink::LinkLeaders linkLeaders = link->getLeaderInfo(this, seen, 0, isShadowLink);
2018  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
2019  // the vehicle to enter the junction first has priority
2020  const MSVehicle* leader = (*it).vehAndGap.first;
2021  if (leader == 0) {
2022  // leader is a pedestrian. Passing 'this' as a dummy.
2023  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
2024  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
2025  } else if (link->isLeader(this, leader)) {
2026  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
2027  if (lastLink != 0) {
2028  // we are not yet on the junction with this linkLeader.
2029  // at least we can drive up to the previous link and stop there
2030  v = MAX2(v, lastLink->myVLinkWait);
2031  }
2032  // if blocked by a leader from the same lane we must yield our request
2033  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
2034  setRequest = false;
2035  }
2036  }
2037  }
2038  // if this is the link between two internal lanes we may have to slow down for pedestrians
2039  vLinkWait = MIN2(vLinkWait, v);
2040 }
2041 
2042 
2043 double
2044 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, double> leaderInfo,
2045  const double seen, const MSLane* const lane, double distToCrossing) const {
2046  assert(leaderInfo.first != 0);
2047  const MSCFModel& cfModel = getCarFollowModel();
2048  double vsafeLeader = 0;
2049  if (leaderInfo.second >= 0) {
2050  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getApparentDecel());
2051  } else {
2052  // the leading, in-lapping vehicle is occupying the complete next lane
2053  // stop before entering this lane
2054  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
2055  }
2056  if (distToCrossing >= 0) {
2057  // drive up to the crossing point with the current link leader
2058  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
2059  }
2060  return vsafeLeader;
2061 }
2062 
2063 double
2064 MSVehicle::getDeltaPos(double accel) {
2065  double vNext = myState.mySpeed + ACCEL2SPEED(accel);
2067  // apply implicit Euler positional update
2068  return SPEED2DIST(MAX2(vNext, 0.));
2069  } else {
2070  // apply ballistic update
2071  if (vNext >= 0) {
2072  // assume constant acceleration during this time step
2073  return SPEED2DIST(myState.mySpeed + 0.5 * ACCEL2SPEED(accel));
2074  } else {
2075  // negative vNext indicates a stop within the middle of time step
2076  // The corresponding stop time is s = mySpeed/deceleration \in [0,dt], and the
2077  // covered distance is therefore deltaPos = mySpeed*s - 0.5*deceleration*s^2.
2078  // Here, deceleration = (myState.mySpeed - vNext)/dt is the constant deceleration
2079  // until the vehicle stops.
2080  return -SPEED2DIST(0.5 * myState.mySpeed * myState.mySpeed / ACCEL2SPEED(accel));
2081  }
2082  }
2083 }
2084 
2085 bool
2087 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2088  if (gDebugSelectedVehicle == getID()) {
2089  int bla = 0;
2090  }
2091 #endif
2092 
2093 #ifdef DEBUG_EXEC_MOVE
2094  if (DEBUG_COND) std::cout << "\nEXECUTE_MOVE\n"
2095  << SIMTIME
2096  << " veh=" << getID()
2097  << " speed=" << getSpeed() // toString(getSpeed(), 24)
2098  << std::endl;
2099 #endif
2100 
2101  // get safe velocities from DriveProcessItems
2102  double vSafe = 0; // maximum safe velocity (XXX: why init this as 0 !? (Leo)) Refs. #2575
2103  double vSafeZipper = std::numeric_limits<double>::max(); // speed limit due to zipper merging
2104  double vSafeMin = 0; // minimum safe velocity
2105  // the distance to a link which should either be crossed this step or in
2106  // front of which we need to stop
2107  double vSafeMinDist = 0;
2108  myHaveToWaitOnNextLink = false;
2109 
2110  assert(myLFLinkLanes.size() != 0 || isRemoteControlled());
2111  DriveItemVector::iterator i;
2112  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
2113  MSLink* link = (*i).myLink;
2114 
2115 #ifdef DEBUG_EXEC_MOVE
2116  if (DEBUG_COND) {
2117  std::cout
2118  << SIMTIME
2119  << " veh=" << getID()
2120  << " link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID())
2121  << " req=" << (*i).mySetRequest
2122  << " vP=" << (*i).myVLinkPass
2123  << " vW=" << (*i).myVLinkWait
2124  << " d=" << (*i).myDistance
2125  << "\n";
2126  gDebugFlag1 = true; // See MSLink_DEBUG_OPENED
2127  }
2128 #endif
2129 
2130  // the vehicle must change the lane on one of the next lanes (XXX: refs to code further below???, Leo)
2131  if (link != 0 && (*i).mySetRequest) {
2132 
2133  const LinkState ls = link->getState();
2134  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
2135  const bool yellow = link->haveYellow();
2136  const bool canBrake = ((*i).myDistance > getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.)
2138  const bool ignoreRedLink = ignoreRed(link, canBrake);
2139  if (yellow && canBrake && !ignoreRedLink) {
2140  vSafe = (*i).myVLinkWait;
2141  myHaveToWaitOnNextLink = true;
2142  link->removeApproaching(this);
2143  break;
2144  }
2145  //
2146 #ifdef NO_TRACI
2147  const bool influencerPrio = false;
2148 #else
2149  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
2150 #endif
2151  std::vector<const SUMOVehicle*> collectFoes;
2152  bool opened = (yellow || influencerPrio
2153  || link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2157  ls == LINKSTATE_ZIPPER ? &collectFoes : 0,
2158  ignoreRedLink));
2159  if (opened && getLaneChangeModel().getShadowLane() != 0) {
2160  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
2161  if (parallelLink != 0) {
2162  const double shadowLatPos = getLateralPositionOnLane() - getLaneChangeModel().getShadowDirection() * 0.5 * (
2164  opened = yellow || influencerPrio || (opened & parallelLink->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2167  getWaitingTime(), shadowLatPos, 0,
2168  ignoreRedLink, this));
2169 #ifdef DEBUG_EXEC_MOVE
2170  if (DEBUG_COND) {
2171  std::cout << SIMTIME
2172  << " veh=" << getID()
2173  << " shadowLane=" << getLaneChangeModel().getShadowLane()->getID()
2174  << " shadowDir=" << getLaneChangeModel().getShadowDirection()
2175  << " parallelLink=" << (parallelLink == 0 ? "NULL" : parallelLink->getViaLaneOrLane()->getID())
2176  << " opened=" << opened
2177  << "\n";
2178  }
2179 #endif
2180  }
2181  }
2182  // vehicles should decelerate when approaching a minor link
2183  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont() && !ignoreRedLink) {
2184  double visibilityDistance = link->getFoeVisibilityDistance();
2185  double determinedFoePresence = i->myDistance <= visibilityDistance;
2186  if (!determinedFoePresence) {
2187  vSafe = (*i).myVLinkWait;
2188  myHaveToWaitOnNextLink = true;
2189  if (ls == LINKSTATE_EQUAL) {
2190  link->removeApproaching(this);
2191  }
2192  break;
2193  } else {
2194  // past the point of no return. we need to drive fast enough
2195  // to make it across the link. However, minor slowdowns
2196  // should be permissible to follow leading traffic safely
2197  // XXX: There is a problem in subsecond simulation: If we cannot
2198  // make it across the minor link in one step, new traffic
2199  // could appear on a major foe link and cause a collision. Refs. #1845, #2123
2200  vSafeMinDist = myLane->getLength() - getPositionOnLane(); // distance that must be covered
2202  vSafeMin = MIN2((double) DIST2SPEED(vSafeMinDist + POSITION_EPS), (*i).myVLinkPass);
2203  } else {
2204  vSafeMin = MIN2((double) DIST2SPEED(2 * vSafeMinDist + NUMERICAL_EPS) - getSpeed(), (*i).myVLinkPass);
2205  }
2206  }
2207  }
2208  // have waited; may pass if opened...
2209  if (opened) {
2210  vSafe = (*i).myVLinkPass;
2211  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
2212  // this vehicle is probably not gonna drive across the next junction (heuristic)
2213  myHaveToWaitOnNextLink = true;
2214  }
2215  } else if (link->getState() == LINKSTATE_ZIPPER) {
2216  vSafeZipper = MIN2(vSafeZipper,
2217  link->getZipperSpeed(this, (*i).myDistance, (*i).myVLinkPass, (*i).myArrivalTime, &collectFoes));
2218  } else {
2219  vSafe = (*i).myVLinkWait;
2220  myHaveToWaitOnNextLink = true;
2221  if (ls == LINKSTATE_EQUAL) {
2222  link->removeApproaching(this);
2223  }
2224 #ifdef DEBUG_EXEC_MOVE
2225  if (DEBUG_COND) {
2226  std::cout << SIMTIME << " braking for closed link=" << link->getViaLaneOrLane()->getID() << "\n";
2227  }
2228 #endif
2229  break;
2230  }
2231  } else {
2232  // we have: i->link == 0 || !i->setRequest
2233  vSafe = (*i).myVLinkWait;
2234  if (vSafe < getSpeed()) {
2235  myHaveToWaitOnNextLink = true;
2236  }
2237  break;
2238  }
2239  }
2240 
2241 //#ifdef DEBUG_EXEC_MOVE
2242 // if (DEBUG_COND) {
2243 // std::cout << "\nvCurrent = " << toString(getSpeed(), 24) << "" << std::endl;
2244 // std::cout << "vSafe = " << toString(vSafe, 24) << "" << std::endl;
2245 // std::cout << "vSafeMin = " << toString(vSafeMin, 24) << "" << std::endl;
2246 // std::cout << "vSafeMinDist = " << toString(vSafeMinDist, 24) << "" << std::endl;
2247 //
2248 // double gap = getLeader().second;
2249 // std::cout << "gap = " << toString(gap, 24) << std::endl;
2250 // std::cout << "vSafeStoppedLeader = " << toString(getCarFollowModel().stopSpeed(this, getSpeed(), gap), 24)
2251 // << "\n" << std::endl;
2252 // }
2253 //#endif
2254 
2255  if ((MSGlobals::gSemiImplicitEulerUpdate && vSafe + NUMERICAL_EPS < vSafeMin)
2256  || (!MSGlobals::gSemiImplicitEulerUpdate && (vSafe + NUMERICAL_EPS < vSafeMin && vSafeMin != 0))) { // this might be good for the euler case as well
2257  // cannot drive across a link so we need to stop before it
2258  // XXX: (Leo) This often called stopSpeed with vSafeMinDist==0 (for the ballistic update), since vSafe can become negative
2259  // 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
2260  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
2261  vSafeMin = 0;
2262  myHaveToWaitOnNextLink = true;
2263 
2264 #ifdef DEBUG_EXEC_MOVE
2265  if (DEBUG_COND) {
2266  std::cout << "vSafeMin Problem?" << std::endl;
2267  }
2268 #endif
2269 
2270  }
2271 
2272  // vehicles inside a roundabout should maintain their requests
2273  if (myLane->getEdge().isRoundabout()) {
2274  myHaveToWaitOnNextLink = false;
2275  }
2276 
2277  vSafe = MIN2(vSafe, vSafeZipper);
2278 
2279 //#ifdef DEBUG_EXEC_MOVE
2280 // if (DEBUG_COND) {
2281 // std::cout << "vSafe = " << toString(vSafe,12) << "\n" << std::endl;
2282 // }
2283 //#endif
2284 
2285  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
2286  double vNext;
2288  vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
2289  } else {
2290  // in case of ballistic position update, negative speeds can indicate desired stops within next timestep.
2291  if (vSafeMin == 0) {
2292  // (Leo) This should be an indication that it would even be safe to stop immediately ("implicit Euler logic")
2293  // Hence, stopping within next the timestep (negative vNext) is tolerated.
2294  vNext = getCarFollowModel().moveHelper(this, vSafe);
2295  } else {
2296  vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
2297  }
2298  // (Leo) to avoid oscillations (< 1e-10) of vNext in a standing vehicle column, we cap off vNext
2299  if (fabs(vNext) < NUMERICAL_EPS) {
2300  vNext = 0.;
2301  }
2302  }
2303 #ifdef DEBUG_EXEC_MOVE
2304  if (DEBUG_COND) {
2305  std::cout << SIMTIME << " moveHelper vSafe=" << vSafe << " vSafeMin=" << vSafeMin << " vNext=" << vNext << "\n";
2306  }
2307 #endif
2308 
2309  // vNext may be higher than vSafe without implying a bug:
2310  // - when approaching a green light that suddenly switches to yellow
2311  // - when using unregulated junctions
2312  // - when using tau < step-size
2313  // - when using unsafe car following models
2314  // - when using TraCI and some speedMode / laneChangeMode settings
2315  //if (vNext > vSafe + NUMERICAL_EPS) {
2316  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
2317  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
2318  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2319  //}
2320 
2322  vNext = MAX2(vNext, 0.);
2323  } else {
2324  // (Leo) Ballistic: negative vNext can be used to indicate a stop within next step.
2325  // moveHelper() should take care of any bounds on the possible deceleration and
2326  // restrict negativity of vNext, e.g., vNext = MAX2(vNext, myState.mySpeed - ACCEL2SPEED(getCarFollowModel().getMaxDecel()));
2327  }
2328 
2329 #ifndef NO_TRACI
2330  if (myInfluencer != 0) {
2331  if (myInfluencer->isVTDControlled()) {
2332  vNext = myInfluencer->implicitSpeedVTD(this, myState.mySpeed);
2333  }
2334  const double vMax = getVehicleType().getCarFollowModel().maxNextSpeed(myState.mySpeed, this);
2335 // const double vMin = MAX2(0., getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
2336  const double vMin = MAX2(0., getVehicleType().getCarFollowModel().minNextSpeed(myState.mySpeed, this));
2337  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
2338  }
2339 #endif
2340  // To avoid casual blinking brake lights at high speeds due to dawdling of the
2341  // leading vehicle, we don't show brake lights when the deceleration could be caused
2342  // by frictional forces and air resistance (i.e. proportional to v^2, coefficient could be adapted further)
2343  double pseudoFriction = (0.05 + 0.005 * getSpeed()) * getSpeed();
2344  bool brakelightsOn = vNext < getSpeed() - ACCEL2SPEED(pseudoFriction);
2345 
2346  // visit waiting time
2347  if (vNext <= SUMO_const_haltingSpeed && !isStopped()) {
2350  brakelightsOn = true;
2351  } else {
2352  myWaitingTime = 0;
2354  }
2355 
2356  if (brakelightsOn) {
2358  } else {
2360  }
2361 
2362  // update position and speed
2363  updateState(vNext);
2364  std::vector<MSLane*> passedLanes;
2365  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
2366  passedLanes.push_back(*i);
2367  }
2368  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
2369  passedLanes.push_back(myLane);
2370  }
2371  bool moved = false; // whether this veh moves to another lane
2372  std::string emergencyReason = " for unknown reasons";
2373  // move on lane(s)
2374  if (myState.myPos > myLane->getLength()) {
2375  // we are moving at least to the next lane (maybe pass even more than one)
2376  if (myCurrEdge != myRoute->end() - 1) {
2377  MSLane* approachedLane = myLane;
2378  // move the vehicle forward
2379  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
2380  MSLink* link = (*i).myLink;
2381  // check whether the vehicle was allowed to enter lane
2382  // otherwise it is decelerated and we do not need to test for it's
2383  // approach on the following lanes when a lane changing is performed
2384  // proceed to the next lane
2385  if (link != 0) {
2386  approachedLane = link->getViaLaneOrLane();
2387 #ifndef NO_TRACI
2389 #endif
2390  if (link->haveRed() && !ignoreRed(link, false)) {
2391  emergencyReason = " because of a red traffic light";
2392  break;
2393  }
2394 #ifndef NO_TRACI
2395  }
2396 #endif
2397  } else if (myState.myPos < myLane->getLength() + NUMERICAL_EPS) {
2398  approachedLane = myLane;
2400  } else {
2401  emergencyReason = " because there is no connection to the next edge";
2402  approachedLane = 0;
2403  break;
2404  }
2405  if (approachedLane != myLane && approachedLane != 0) {
2407  myState.myPos -= myLane->getLength();
2408  assert(myState.myPos > 0);
2409  enterLaneAtMove(approachedLane);
2411  // erase leaders when past the junction
2412  if (link->getViaLane() == 0) {
2413  link->passedJunction(this);
2414  }
2415  }
2416  if (hasArrived()) {
2417  break;
2418  }
2419  if (getLaneChangeModel().isChangingLanes()) {
2420  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
2421  // abort lane change
2422  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
2423  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2425  }
2426  }
2427  moved = true;
2428  if (approachedLane->getEdge().isVaporizing()) {
2430  break;
2431  }
2432  }
2433  passedLanes.push_back(approachedLane);
2434  }
2435  }
2436  }
2437  // update time loss (depends on the updated edge)
2438  if (!isStopped()) {
2439  const double vmax = myLane->getVehicleMaxSpeed(this);
2440  if (vmax > 0) {
2441  myTimeLoss += TIME2STEPS(TS * (vmax - vNext) / vmax);
2442  }
2443  }
2445 
2446  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
2447  if (myState.myPos > myLane->getLength()) {
2448  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
2449  + "'" + emergencyReason
2450  + " (decel=" + toString(myAcceleration - myState.mySpeed)
2451  + ", offset = " + toString(myState.myPos - myLane->getLength())
2452  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2455  myState.mySpeed = 0;
2456  }
2457  const MSLane* oldBackLane = getBackLane();
2458  if (getLaneChangeModel().isOpposite()) {
2459  passedLanes.clear(); // ignore back occupation
2460  }
2462  // bestLanes need to be updated before lane changing starts
2463  updateBestLanes();
2464  // shadow lane must be updated if the front or back lane changed
2465  // either if we already have a shadowLane or if there is lateral overlap
2466  if ((getLaneChangeModel().getShadowLane() != 0 || getLateralOverlap() > POSITION_EPS)
2467  && (moved || oldBackLane != getBackLane())) {
2469  }
2470  setBlinkerInformation(); // needs updated bestLanes
2471  //change the blue light only for emergency vehicles SUMOVehicleClass
2472  if (myType->getVehicleClass() == SVC_EMERGENCY) {
2473  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
2474  }
2475  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
2477  myAngle = computeAngle();
2478  }
2479 
2480 #ifdef DEBUG_EXEC_MOVE
2481  if (DEBUG_COND) {
2482  std::cout << SIMTIME << " executeMove finished veh=" << getID() << " lane=" << myLane->getID() << " myPos=" << getPositionOnLane() << " myPosLat=" << getLateralPositionOnLane() << "\n";
2483  gDebugFlag1 = false; // See MSLink_DEBUG_OPENED
2484  }
2485 #endif
2486  if (getLaneChangeModel().isOpposite()) {
2487  // transform back to the opposite-direction lane
2488  if (myLane->getOpposite() == 0) {
2489  WRITE_WARNING("Unexpected end of opposite lane for vehicle '" + getID() + " at lane '" + myLane->getID() + "', time=" +
2490  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2492  } else {
2494  myLane = myLane->getOpposite();
2496  }
2497  }
2499  return moved;
2500 }
2501 
2502 
2503 void
2504 MSVehicle::updateState(double vNext) {
2505  // update position and speed
2506  double deltaPos; // positional change
2508  deltaPos = SPEED2DIST(vNext);
2509  } else {
2510  // ballistic
2511  // XXX: this is ok for the euler update, too. However, small differences
2512  // will to the above formula result from rounding. (introduced this too have
2513  // exact cooincidence of test results, refactor after merge to trunk)
2514  deltaPos = getDeltaPos(SPEED2ACCEL(vNext - myState.mySpeed));
2515  }
2516 
2517  // the *mean* acceleration during the next step (probably most appropriate for emission calculation)
2518  // TODO: recheck, approve, refs. #2579
2519  // NOTE: for the ballistic update this is in general
2520  // not equal to vNext - myState.mySpeed
2521  myAcceleration = SPEED2ACCEL(MAX2(vNext, 0.) - myState.mySpeed);
2522 
2523 //#ifdef DEBUG_EXEC_MOVE
2524 // if (DEBUG_COND) {
2525 // std::cout << "deltaPos = " << deltaPos << std::endl;
2526 // }
2527 //#endif
2528 
2530  myState.mySpeed = MAX2(vNext, 0.);
2531 
2532 #ifndef NO_TRACI
2533  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
2534  deltaPos = myInfluencer->implicitDeltaPosVTD(this);
2535  }
2536 #endif
2537 
2538  if (getLaneChangeModel().isOpposite()) {
2539  // transform to the forward-direction lane, move and then transform back
2541  myLane = myLane->getOpposite();
2542  }
2543  myState.myPos += deltaPos;
2544  myState.myLastCoveredDist = deltaPos;
2545 
2547 }
2548 
2549 
2550 const MSLane*
2552  if (myFurtherLanes.size() > 0) {
2553  return myFurtherLanes.back();
2554  } else {
2555  return myLane;
2556  }
2557 }
2558 
2559 
2560 double
2561 MSVehicle::updateFurtherLanes(std::vector<MSLane*>& furtherLanes, std::vector<double>& furtherLanesPosLat,
2562  const std::vector<MSLane*>& passedLanes) {
2563 
2564  // XXX only reset / set the values that were changed
2565 #ifdef DEBUG_FURTHER
2566  if (DEBUG_COND) std::cout << SIMTIME
2567  << " updateFurtherLanes oldFurther=" << toString(furtherLanes)
2568  << " oldFurtherPosLat=" << toString(furtherLanesPosLat)
2569  << " passed=" << toString(passedLanes)
2570  << "\n";
2571 #endif
2572  for (std::vector<MSLane*>::iterator i = furtherLanes.begin(); i != furtherLanes.end(); ++i) {
2573  (*i)->resetPartialOccupation(this);
2574  }
2575  const MSLane* firstOldFurther = furtherLanes.size() > 0 ? furtherLanes.front() : 0;
2576  bool newFurther = true;
2577  // update furtherLanes
2578  double result = myState.myPos - getVehicleType().getLength();
2579  furtherLanes.clear();
2580  if (passedLanes.size() > 0) {
2581  double leftLength = getVehicleType().getLength() - myState.myPos;
2582  std::vector<MSLane*>::const_reverse_iterator i = passedLanes.rbegin() + 1;
2583  while (leftLength > 0 && i != passedLanes.rend()) {
2584  furtherLanes.push_back(*i);
2585  // add new lateral values until hitting the first known further lane
2586  if (*i == firstOldFurther) {
2587  newFurther = false;
2588  }
2589  if (newFurther) {
2590  furtherLanesPosLat.insert(furtherLanesPosLat.begin(), myState.myPosLat);
2591  }
2592 #ifdef DEBUG_FURTHER
2593  if (DEBUG_COND) {
2594  std::cout << SIMTIME << " updateFurtherLanes \n";
2595  }
2596 #endif
2597  leftLength -= (*i)->setPartialOccupation(this);
2598  ++i;
2599  }
2600  result = -leftLength;
2601  }
2602  assert(furtherLanesPosLat.size() >= furtherLanes.size());
2603  furtherLanesPosLat.erase(furtherLanesPosLat.begin() + furtherLanes.size(), furtherLanesPosLat.end());
2604  assert(furtherLanesPosLat.size() == furtherLanes.size());
2605 #ifdef DEBUG_FURTHER
2606  if (DEBUG_COND) std::cout
2607  << " newFurther=" << toString(furtherLanes)
2608  << " newFurtherPosLat=" << toString(furtherLanesPosLat)
2609  << " newBackPos=" << result
2610  << "\n";
2611 #endif
2612  return result;
2613 }
2614 
2615 
2616 double
2618 #ifdef DEBUG_FURTHER
2619  //if (DEBUG_COND) std::cout << SIMTIME
2620  // << " getBackPositionOnLane veh=" << getID()
2621  // << " lane=" << Named::getIDSecure(lane)
2622  // << " myLane=" << myLane->getID()
2623  // << " further=" << toString(myFurtherLanes)
2624  // << " furtherPosLat=" << toString(myFurtherLanesPosLat)
2625  // << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
2626  // << " shadowFurther=" << toString(getLaneChangeModel().getShadowFurtherLanes())
2627  // << " shadowFurtherPosLat=" << toString(getLaneChangeModel().getShadowFurtherLanesPosLat())
2628  // << "\n";
2629 #endif
2630  if (lane == myLane
2631  || lane == getLaneChangeModel().getShadowLane()) {
2632  if (getLaneChangeModel().isOpposite()) {
2633  return myState.myPos + myType->getLength();
2634  } else {
2635  return myState.myPos - myType->getLength();
2636  }
2637  } else if ((myFurtherLanes.size() > 0 && lane == myFurtherLanes.back())
2638  || (getLaneChangeModel().getShadowFurtherLanes().size() > 0 && lane == getLaneChangeModel().getShadowFurtherLanes().back())
2639  ) {
2640  return myState.myBackPos;
2641  } else {
2642  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myFurtherLanes=" << toString(myFurtherLanes) << "\n";
2643  double leftLength = myType->getLength() - myState.myPos;
2644  std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin();
2645  while (leftLength > 0 && i != myFurtherLanes.end()) {
2646  leftLength -= (*i)->getLength();
2647  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2648  if (*i == lane) {
2649  return -leftLength;
2650  }
2651  ++i;
2652  }
2653  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
2654  leftLength = myType->getLength() - myState.myPos;
2655  i = getLaneChangeModel().getShadowFurtherLanes().begin();
2656  while (leftLength > 0 && i != getLaneChangeModel().getShadowFurtherLanes().end()) {
2657  leftLength -= (*i)->getLength();
2658  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2659  if (*i == lane) {
2660  return -leftLength;
2661  }
2662  ++i;
2663  }
2664  assert(false);
2665  WRITE_WARNING("Request backPos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane)
2666  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
2667  return myState.myBackPos;
2668  }
2669 }
2670 
2671 
2672 double
2674  return getBackPositionOnLane(lane) + myType->getLength();
2675 }
2676 
2677 
2678 bool
2679 MSVehicle::isFrontOnLane(const MSLane* lane) const {
2680  return lane == myLane || lane == getLaneChangeModel().getShadowLane();
2681 }
2682 
2683 
2684 double
2685 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
2686  double lengths = 0;
2687  const MSLane::VehCont& vehs = l->getVehiclesSecure();
2688  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2689  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()
2690  && (*i) != this
2691  // @todo recheck
2692  && (*i)->isFrontOnLane(l)) {
2693  foundStopped = true;
2694  const double ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
2695  l->releaseVehicles();
2696  return ret;
2697  }
2698  lengths += (*i)->getVehicleType().getLengthWithGap();
2699  }
2700  l->releaseVehicles();
2701  return l->getLength() - lengths;
2702 }
2703 
2704 
2705 void
2706 MSVehicle::checkRewindLinkLanes(const double lengthsInFront, DriveItemVector& lfLinks) const {
2707 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2708  if (gDebugSelectedVehicle == getID()) {
2709  int bla = 0;
2710  }
2711 #endif
2713  bool hadVehicle = false;
2714  double seenSpace = -lengthsInFront;
2715 
2716  bool foundStopped = false;
2717  // compute available space until a stopped vehicle is found
2718  // this is the sum of non-interal lane length minus in-between vehicle lenghts
2719  for (int i = 0; i < (int)lfLinks.size(); ++i) {
2720  // skip unset links
2721  DriveProcessItem& item = lfLinks[i];
2722  if (item.myLink == 0 || foundStopped) {
2723  if (!foundStopped) {
2724  item.availableSpace += seenSpace;
2725  } else {
2726  item.availableSpace = seenSpace;
2727  }
2728  item.hadVehicle = hadVehicle;
2729  continue;
2730  }
2731  // get the next lane, determine whether it is an internal lane
2732  const MSLane* approachedLane = item.myLink->getViaLane();
2733  if (approachedLane != 0) {
2734  if (keepClear(item.myLink)) {
2735  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
2736  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2737  if (approachedLane == myLane) {
2738  seenSpace += getVehicleType().getLengthWithGap();
2739  }
2740  } else {
2741  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2742  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2743  }
2744  item.availableSpace = seenSpace;
2745  item.hadVehicle = hadVehicle;
2746 #ifdef DEBUG_PLAN_MOVE
2747  if (DEBUG_COND) std::cout
2748  << SIMTIME
2749  << " veh=" << getID()
2750  << " approached=" << approachedLane->getID()
2751  << " approachedBrutto=" << approachedLane->getBruttoVehLenSum()
2752  << " avail=" << item.availableSpace
2753  << " seenSpace=" << seenSpace
2754  << " hadVehicle=" << item.hadVehicle
2755  << " lengthsInFront=" << lengthsInFront
2756  << "\n";
2757 #endif
2758  continue;
2759  }
2760  approachedLane = item.myLink->getLane();
2761  const MSVehicle* last = approachedLane->getLastAnyVehicle();
2762  if (last == 0 || last == this) {
2763  seenSpace += approachedLane->getLength();
2764  item.availableSpace = seenSpace;
2765  } else if (!last->isFrontOnLane(approachedLane)) {
2768  item.availableSpace = MAX2(seenSpace, seenSpace + last->getBackPositionOnLane(approachedLane) + last->getCarFollowModel().brakeGap(last->getSpeed()));
2769  hadVehicle = true;
2771  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2773  if (last->myHaveToWaitOnNextLink) {
2774  foundStopped = true;
2775  }
2776 #ifdef DEBUG_PLAN_MOVE
2777  if (DEBUG_COND) std::cout
2778  << SIMTIME
2779  << " veh=" << getID()
2780  << " approached=" << approachedLane->getID()
2781  << " lastPoc=" << last->getID()
2782  << " avail=" << item.availableSpace
2783  << " seenSpace=" << seenSpace
2784  << " foundStopped=" << foundStopped
2785  << "\n";
2786 #endif
2787  } else {
2788 
2789  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
2790  const double lastBrakeGap = last->getCarFollowModel().brakeGap(last->getSpeed());
2791  const double lastGap = last->getBackPositionOnLane(approachedLane) + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime()
2792  // gap of last up to the next intersection
2793  - last->getVehicleType().getMinGap();
2794  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
2795  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2796  } else {
2797  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
2798  item.availableSpace = seenSpace;
2799  }
2800  if (last->myHaveToWaitOnNextLink) {
2801  foundStopped = true;
2802  }
2803  hadVehicle = true;
2804 #ifdef DEBUG_PLAN_MOVE
2805  if (DEBUG_COND) std::cout
2806  << SIMTIME
2807  << " veh=" << getID()
2808  << " approached=" << approachedLane->getID()
2809  << " last=" << last->getID()
2810  << " avail=" << item.availableSpace
2811  << " seenSpace=" << seenSpace
2812  << " foundStopped=" << foundStopped
2813  << "\n";
2814 #endif
2815  }
2816  item.hadVehicle = hadVehicle;
2817  }
2818 
2819 
2820 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2821  if (gDebugSelectedVehicle == getID()) {
2822  int bla = 0;
2823  }
2824 #endif
2825  // check which links allow continuation and add pass available to the previous item
2826  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
2827  DriveProcessItem& item = lfLinks[i - 1];
2828  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
2829  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
2830 #ifndef NO_TRACI
2832 #endif
2833  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
2836  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
2837  if (!opened && item.myLink != 0) {
2838  if (i > 1) {
2839  DriveProcessItem& item2 = lfLinks[i - 2];
2840  if (item2.myLink != 0 && item2.myLink->isCont()) {
2841  allowsContinuation = true;
2842  }
2843  }
2844  }
2845  if (allowsContinuation) {
2846  item.availableSpace = lfLinks[i].availableSpace;
2847  }
2848  }
2849 
2850  // find removalBegin
2851  int removalBegin = -1;
2852  for (int i = 0; hadVehicle && i < (int)lfLinks.size() && removalBegin < 0; ++i) {
2853  // skip unset links
2854  const DriveProcessItem& item = lfLinks[i];
2855  if (item.myLink == 0) {
2856  continue;
2857  }
2858  /*
2859  double impatienceCorrection = MAX2(0., double(double(myWaitingTime)));
2860  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
2861  removalBegin = lastLinkToInternal;
2862  }
2863  */
2864 
2865  const double leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
2866  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
2867  double impatienceCorrection = 0;
2868  /*
2869  if(item.myLink->getState()==LINKSTATE_MINOR) {
2870  impatienceCorrection = MAX2(0., STEPS2TIME(myWaitingTime));
2871  }
2872  */
2873  // may ignore keepClear rules
2874  if (leftSpace < -impatienceCorrection / 10. && keepClear(item.myLink)) {
2875  removalBegin = i;
2876  }
2877  //removalBegin = i;
2878  }
2879  }
2880  // abort requests
2881  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().isInternal())) {
2882  while (removalBegin < (int)(lfLinks.size())) {
2883  const double brakeGap = getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.);
2884  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
2885  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
2886  lfLinks[removalBegin].mySetRequest = false;
2887  }
2888  ++removalBegin;
2889  }
2890  }
2891  }
2892  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2893  if ((*i).myLink != 0) {
2894  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
2895  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((int)2); // tie braker
2896  }
2897  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2898  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2899  }
2900  }
2901  if (getLaneChangeModel().getShadowLane() != 0) {
2902  // register on all shadow links
2903  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2904  if ((*i).myLink != 0) {
2905  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
2906  if (parallelLink != 0) {
2907  parallelLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2908  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2910  }
2911  }
2912  }
2913  }
2914 }
2915 
2916 
2917 void
2919  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2920  // skip the reminder if it is a lane reminder but not for my lane (indicated by rem->second > 0.)
2921  if (rem->first->getLane() != 0 && rem->second > 0.) {
2922 #ifdef _DEBUG
2923  if (myTraceMoveReminders) {
2924  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
2925  }
2926 #endif
2927  ++rem;
2928  } else {
2929  if (rem->first->notifyEnter(*this, reason, enteredLane)) {
2930 #ifdef _DEBUG
2931  if (myTraceMoveReminders) {
2932  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
2933  }
2934 #endif
2935  ++rem;
2936  } else {
2937 #ifdef _DEBUG
2938  if (myTraceMoveReminders) {
2939  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
2940  }
2941 // std::cout << SIMTIME << " Vehicle '" << getID() << "' erases MoveReminder (with offset " << rem->second << ")" << std::endl;
2942 #endif
2943  rem = myMoveReminders.erase(rem);
2944  }
2945  }
2946  }
2947 }
2948 
2949 
2950 bool
2951 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
2952  myAmOnNet = !onTeleporting;
2953  // vaporizing edge?
2954  /*
2955  if (enteredLane->getEdge().isVaporizing()) {
2956  // yep, let's do the vaporization...
2957  myLane = enteredLane;
2958  return true;
2959  }
2960  */
2961  // Adjust MoveReminder offset to the next lane
2962  adaptLaneEntering2MoveReminder(*enteredLane);
2963  // set the entered lane as the current lane
2964  myLane = enteredLane;
2965  myLastBestLanesEdge = 0;
2966 
2967  // internal edges are not a part of the route...
2968  if (!enteredLane->getEdge().isInternal()) {
2969  ++myCurrEdge;
2970  }
2971  if (!onTeleporting) {
2973  } else {
2974  // normal move() isn't called so reset position here. must be done
2975  // before calling reminders
2976  myState.myPos = 0;
2979  }
2980  // update via
2981  if (myParameter->via.size() > 0 && myLane->getEdge().getID() == myParameter->via.front()) {
2982  myParameter->via.erase(myParameter->via.begin());
2983  }
2984  return hasArrived();
2985 }
2986 
2987 
2988 void
2990  myAmOnNet = true;
2991  myLane = enteredLane;
2993  // need to update myCurrentLaneInBestLanes
2994  updateBestLanes();
2995  // switch to and activate the new lane's reminders
2996  // keep OldLaneReminders
2997  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2998  addReminder(*rem);
2999  }
3001  MSLane* lane = myLane;
3002  double leftLength = getVehicleType().getLength() - myState.myPos;
3003  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
3004  if (lane != 0) {
3005  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
3006  }
3007  if (lane != 0) {
3008 #ifdef DEBUG_FURTHER
3009  if (DEBUG_COND) {
3010  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
3011  }
3012 #endif
3013  myFurtherLanes[i]->resetPartialOccupation(this);
3014  myFurtherLanes[i] = lane;
3016 #ifdef DEBUG_FURTHER
3017  if (DEBUG_COND) {
3018  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
3019  }
3020 #endif
3021  leftLength -= (lane)->setPartialOccupation(this);
3022  } else {
3023  // keep the old values, but ensure there is no shadow
3026  }
3027  }
3028  }
3029 #ifdef DEBUG_FURTHER
3030  if (DEBUG_COND) {
3031  std::cout << SIMTIME << " enterLaneAtLaneChange new furtherLanes=" << toString(myFurtherLanes) << "\n";
3032  }
3033 #endif
3034  myAngle = computeAngle();
3035 }
3036 
3037 
3038 void
3039 MSVehicle::enterLaneAtInsertion(MSLane* enteredLane, double pos, double speed, double posLat, MSMoveReminder::Notification notification) {
3040  myState = State(pos, speed, posLat, pos - getVehicleType().getLength());
3041  if (myDeparture == NOT_YET_DEPARTED) {
3042  onDepart();
3043  }
3045  assert(myState.myPos >= 0);
3046  assert(myState.mySpeed >= 0);
3047  myLane = enteredLane;
3048  myAmOnNet = true;
3049  if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
3050  // set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
3051  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
3052  addReminder(*rem);
3053  }
3054  activateReminders(notification, enteredLane);
3055  }
3056  // build the list of lanes the vehicle is lapping into
3057  if (!myLaneChangeModel->isOpposite()) {
3058  double leftLength = myType->getLength() - pos;
3059  MSLane* clane = enteredLane;
3060  while (leftLength > 0) {
3061  clane = clane->getLogicalPredecessorLane();
3062  if (clane == 0 || clane == myLane) {
3063  break;
3064  }
3065  myFurtherLanes.push_back(clane);
3067  leftLength -= (clane)->setPartialOccupation(this);
3068  }
3069  myState.myBackPos = -leftLength;
3070  } else {
3071  // clear partial occupation
3072  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
3073 #ifdef DEBUG_FURTHER
3074  if (DEBUG_COND) {
3075  std::cout << SIMTIME << " enterLaneAtInsertion \n";
3076  }
3077 #endif
3078  (*i)->resetPartialOccupation(this);
3079  }
3080  myFurtherLanes.clear();
3081  myFurtherLanesPosLat.clear();
3082  }
3085  }
3086  myAngle = computeAngle();
3087  if (getLaneChangeModel().isOpposite()) {
3088  myAngle += M_PI;
3089  }
3090 }
3091 
3092 
3093 void
3094 MSVehicle::leaveLane(const MSMoveReminder::Notification reason, const MSLane* approachedLane) {
3095  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
3096  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason, approachedLane)) {
3097 #ifdef _DEBUG
3098  if (myTraceMoveReminders) {
3099  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
3100  }
3101 #endif
3102  ++rem;
3103  } else {
3104 #ifdef _DEBUG
3105  if (myTraceMoveReminders) {
3106  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
3107  }
3108 #endif
3109  rem = myMoveReminders.erase(rem);
3110  }
3111  }
3113  // @note. In case of lane change, myFurtherLanes and partial occupation
3114  // are handled in enterLaneAtLaneChange()
3115  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
3116 #ifdef DEBUG_FURTHER
3117  if (DEBUG_COND) {
3118  std::cout << SIMTIME << " leaveLane \n";
3119  }
3120 #endif
3121  (*i)->resetPartialOccupation(this);
3122  }
3123  myFurtherLanes.clear();
3124  myFurtherLanesPosLat.clear();
3125  }
3126  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
3127  myAmOnNet = false;
3128  myWaitingTime = 0;
3129  }
3131  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
3132  }
3134  while (!myStops.empty() && myStops.front().edge == myCurrEdge && &myStops.front().lane->getEdge() == &myLane->getEdge()) {
3135  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
3136  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
3137  myStops.pop_front();
3138  }
3139  }
3140 }
3141 
3142 
3145  return *myLaneChangeModel;
3146 }
3147 
3148 
3151  return *myLaneChangeModel;
3152 }
3153 
3154 
3155 const std::vector<MSVehicle::LaneQ>&
3157  return *myBestLanes.begin();
3158 }
3159 
3160 
3161 void
3162 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
3163 #ifdef DEBUG_BESTLANES
3164  if (DEBUG_COND) {
3165  std::cout << SIMTIME << " updateBestLanes veh=" << getID() << " startLane1=" << Named::getIDSecure(startLane) << " myLane=" << Named::getIDSecure(myLane) << "\n";
3166  }
3167 #endif
3168 #ifdef DEBUG_VEHICLE_GUI_SELECTION
3169  if (gDebugSelectedVehicle == getID()) {
3170  int bla = 0;
3171  myLastBestLanesEdge = 0;
3172  }
3173 #endif
3174  if (startLane == 0) {
3175  startLane = myLane;
3176  }
3177  assert(startLane != 0);
3178  if (getLaneChangeModel().isOpposite()) {
3179  // depending on the calling context, startLane might be the forward lane
3180  // or the reverse-direction lane. In the latter case we need to
3181  // transform it to the forward lane.
3182  bool startLaneIsOpposite = (startLane->isInternal()
3183  ? & (startLane->getLinkCont()[0]->getLane()->getEdge()) != *(myCurrEdge + 1)
3184  : &startLane->getEdge() != *myCurrEdge);
3185  if (startLaneIsOpposite) {
3186  startLane = startLane->getOpposite();
3187  assert(startLane != 0);
3188  }
3189  }
3190  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
3192  return;
3193  }
3194  if (startLane->getEdge().isInternal()) {
3195  if (myBestLanes.size() == 0 || forceRebuild) {
3196  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
3197  updateBestLanes(true, startLane->getLogicalPredecessorLane());
3198  }
3199  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
3200  return;
3201  }
3202  // adapt best lanes to fit the current internal edge:
3203  // keep the entries that are reachable from this edge
3204  const MSEdge* nextEdge = startLane->getNextNormal();
3205  assert(!nextEdge->isInternal());
3206  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
3207  std::vector<LaneQ>& lanes = *it;
3208  assert(lanes.size() > 0);
3209  if (&(lanes[0].lane->getEdge()) == nextEdge) {
3210  // keep those lanes which are successors of internal lanes from the edge of startLane
3211  std::vector<LaneQ> oldLanes = lanes;
3212  lanes.clear();
3213  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
3214  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
3215  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
3216  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
3217  lanes.push_back(*it_lane);
3218  break;
3219  }
3220  }
3221  }
3222  assert(lanes.size() == startLane->getEdge().getLanes().size());
3223  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
3224  for (int i = 0; i < (int)lanes.size(); ++i) {
3225  if (i + lanes[i].bestLaneOffset < 0) {
3226  lanes[i].bestLaneOffset = -i;
3227  }
3228  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
3229  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
3230  }
3231  assert(i + lanes[i].bestLaneOffset >= 0);
3232  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
3233  if (lanes[i].bestContinuations[0] != 0) {
3234  // patch length of bestContinuation to match expectations (only once)
3235  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
3236  }
3237  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
3238  myCurrentLaneInBestLanes = lanes.begin() + i;
3239  }
3240  assert(&(lanes[i].lane->getEdge()) == nextEdge);
3241  }
3242  myLastBestLanesInternalLane = startLane;
3244  return;
3245  } else {
3246  // remove passed edges
3247  it = myBestLanes.erase(it);
3248  }
3249  }
3250  assert(false); // should always find the next edge
3251  }
3252  // start rebuilding
3253  myLastBestLanesEdge = &startLane->getEdge();
3254  myBestLanes.clear();
3255 
3256  // get information about the next stop
3257  MSRouteIterator nextStopEdge = myRoute->end();
3258  const MSLane* nextStopLane = 0;
3259  double nextStopPos = 0;
3260  if (!myStops.empty()) {
3261  const Stop& nextStop = myStops.front();
3262  nextStopLane = nextStop.lane;
3263  nextStopEdge = nextStop.edge;
3264  nextStopPos = nextStop.startPos;
3265  }
3266  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == myRoute->end()) {
3267  nextStopEdge = (myRoute->end() - 1);
3268  nextStopLane = (*nextStopEdge)->getLanes()[myArrivalLane];
3269  nextStopPos = myArrivalPos;
3270  }
3271  if (nextStopEdge != myRoute->end()) {
3272  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
3273  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
3274  nextStopPos = MAX2(POSITION_EPS, MIN2((double)nextStopPos, (double)(nextStopLane->getLength() - 2 * POSITION_EPS)));
3275  if (nextStopLane->isInternal()) {
3276  nextStopPos += (*nextStopEdge)->getLength();
3277  }
3278  }
3279 
3280  // go forward along the next lanes;
3281  int seen = 0;
3282  double seenLength = 0;
3283  bool progress = true;
3284  for (MSRouteIterator ce = myCurrEdge; progress;) {
3285  std::vector<LaneQ> currentLanes;
3286  const std::vector<MSLane*>* allowed = 0;
3287  const MSEdge* nextEdge = 0;
3288  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
3289  nextEdge = *(ce + 1);
3290  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
3291  }
3292  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
3293  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
3294  LaneQ q;
3295  MSLane* cl = *i;
3296  q.lane = cl;
3297  q.bestContinuations.push_back(cl);
3298  q.bestLaneOffset = 0;
3299  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
3300  q.currentLength = q.length;
3301  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
3302  q.occupation = 0;
3303  q.nextOccupation = 0;
3304  currentLanes.push_back(q);
3305  }
3306  //
3307  if (nextStopEdge == ce && !nextStopLane->isInternal()) {
3308  progress = false;
3309  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
3310  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
3311  (*q).allowsContinuation = false;
3312  (*q).length = nextStopPos;
3313  (*q).currentLength = (*q).length;
3314  }
3315  }
3316  }
3317 
3318  myBestLanes.push_back(currentLanes);
3319  ++seen;
3320  seenLength += currentLanes[0].lane->getLength();
3321  ++ce;
3322  progress &= (seen <= 4 || seenLength < 3000);
3323  progress &= seen <= 8;
3324  progress &= ce != myRoute->end();
3325  /*
3326  if(progress) {
3327  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
3328  }
3329  */
3330  }
3331 
3332  // we are examining the last lane explicitly
3333  if (myBestLanes.size() != 0) {
3334  double bestLength = -1;
3335  int bestThisIndex = 0;
3336  int index = 0;
3337  std::vector<LaneQ>& last = myBestLanes.back();
3338  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
3339  if ((*j).length > bestLength) {
3340  bestLength = (*j).length;
3341  bestThisIndex = index;
3342  }
3343  }
3344  index = 0;
3345  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
3346  if ((*j).length < bestLength) {
3347  (*j).bestLaneOffset = bestThisIndex - index;
3348  }
3349  }
3350  }
3351 #ifdef DEBUG_BESTLANES
3352  if (DEBUG_COND) {
3353  std::cout << " last edge:\n";
3354  std::vector<LaneQ>& laneQs = myBestLanes.back();
3355  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
3356  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
3357  }
3358  }
3359 #endif
3360  // go backward through the lanes
3361  // track back best lane and compute the best prior lane(s)
3362  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
3363  std::vector<LaneQ>& nextLanes = (*(i - 1));
3364  std::vector<LaneQ>& clanes = (*i);
3365  MSEdge& cE = clanes[0].lane->getEdge();
3366  int index = 0;
3367  double bestConnectedLength = -1;
3368  double bestLength = -1;
3369  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
3370  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
3371  bestConnectedLength = (*j).length;
3372  }
3373  if (bestLength < (*j).length) {
3374  bestLength = (*j).length;
3375  }
3376  }
3377  // compute index of the best lane (highest length and least offset from the best next lane)
3378  int bestThisIndex = 0;
3379  if (bestConnectedLength > 0) {
3380  index = 0;
3381  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
3382  LaneQ bestConnectedNext;
3383  bestConnectedNext.length = -1;
3384  if ((*j).allowsContinuation) {
3385  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
3386  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
3387  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
3388  bestConnectedNext = *m;
3389  }
3390  }
3391  }
3392  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
3393  (*j).length += bestLength;
3394  } else {
3395  (*j).length += bestConnectedNext.length;
3396  }
3397  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
3398  }
3399  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
3400  if (clanes[bestThisIndex].length < (*j).length
3401  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))
3402  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) == abs((*j).bestLaneOffset) &&
3403  nextLinkPriority(clanes[bestThisIndex].bestContinuations) < nextLinkPriority((*j).bestContinuations))
3404  ) {
3405  bestThisIndex = index;
3406  }
3407  }
3408 #ifdef DEBUG_BESTLANES
3409  if (DEBUG_COND) {
3410  std::cout << " edge=" << cE.getID() << "\n";
3411  std::vector<LaneQ>& laneQs = clanes;
3412  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
3413  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
3414  }
3415  }
3416 #endif
3417 
3418  } else {
3419  // only needed in case of disconnected routes
3420  int bestNextIndex = 0;
3421  int bestDistToNeeded = (int) clanes.size();
3422  index = 0;
3423  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
3424  if ((*j).allowsContinuation) {
3425  int nextIndex = 0;
3426  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
3427  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
3428  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
3429  bestDistToNeeded = abs((*m).bestLaneOffset);
3430  bestThisIndex = index;
3431  bestNextIndex = nextIndex;
3432  }
3433  }
3434  }
3435  }
3436  }
3437  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
3438  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
3439 
3440  }
3441  // set bestLaneOffset for all lanes
3442  index = 0;
3443  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
3444  if ((*j).length < clanes[bestThisIndex].length
3445  || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))
3446  || (nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)
3447  ) {
3448  (*j).bestLaneOffset = bestThisIndex - index;
3449  if ((nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)) {
3450  // try to move away from the lower-priority lane before it ends
3451  (*j).length = (*j).currentLength;
3452  }
3453  } else {
3454  (*j).bestLaneOffset = 0;
3455  }
3456  }
3457  }
3459 #ifdef DEBUG_BESTLANES
3460  if (DEBUG_COND) {
3461  std::cout << SIMTIME << " veh=" << getID() << " bestCont=" << toString(getBestLanesContinuation()) << "\n";
3462  }
3463 #endif
3464  return;
3465 }
3466 
3467 
3468 int
3469 MSVehicle::nextLinkPriority(const std::vector<MSLane*>& conts) {
3470  if (conts.size() < 2) {
3471  return -1;
3472  } else {
3473  MSLink* link = MSLinkContHelper::getConnectingLink(*conts[0], *conts[1]);
3474  if (link != 0) {
3475  return link->havePriority() ? 1 : 0;
3476  } else {
3477  // disconnected route
3478  return -1;
3479  }
3480  }
3481 }
3482 
3483 
3484 void
3486  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
3487  std::vector<LaneQ>::iterator i;
3488  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
3489  double nextOccupation = 0;
3490  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
3491  nextOccupation += (*j)->getBruttoVehLenSum();
3492  }
3493  (*i).nextOccupation = nextOccupation;
3494  if ((*i).lane == startLane) {
3496  }
3497  }
3498 }
3499 
3500 
3501 const std::vector<MSLane*>&
3503  if (myBestLanes.empty() || myBestLanes[0].empty()) {
3504  return myEmptyLaneVector;
3505  }
3506  return (*myCurrentLaneInBestLanes).bestContinuations;
3507 }
3508 
3509 
3510 const std::vector<MSLane*>&
3512  const MSLane* lane = l;
3513  // XXX: shouldn't this be a "while" to cover more than one internal lane? (Leo) Refs. #2575
3514  if (lane->getEdge().isInternal()) {
3515  // internal edges are not kept inside the bestLanes structure
3516  lane = lane->getLinkCont()[0]->getLane();
3517  }
3518  if (myBestLanes.size() == 0) {
3519  return myEmptyLaneVector;
3520  }
3521  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
3522  if ((*i).lane == lane) {
3523  return (*i).bestContinuations;
3524  }
3525  }
3526  return myEmptyLaneVector;
3527 }
3528 
3529 
3530 int
3532  if (myBestLanes.empty() || myBestLanes[0].empty()) {
3533  return 0;
3534  } else {
3535  return (*myCurrentLaneInBestLanes).bestLaneOffset;
3536  }
3537 }
3538 
3539 
3540 void
3541 MSVehicle::adaptBestLanesOccupation(int laneIndex, double density) {
3542  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
3543  assert(laneIndex < (int)preb.size());
3544  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
3545 }
3546 
3547 
3548 void
3550  if (MSGlobals::gLaneChangeDuration > 0 && !getLaneChangeModel().isChangingLanes()) {
3551  myState.myPosLat = 0;
3552  }
3553 }
3554 
3555 
3556 double
3557 MSVehicle::getDistanceToPosition(double destPos, const MSEdge* destEdge) const {
3558  double distance = std::numeric_limits<double>::max();
3559  if (isOnRoad() && destEdge != NULL) {
3560  if (&myLane->getEdge() == *myCurrEdge) {
3561  // vehicle is on a normal edge
3562  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
3563  } else {
3564  // vehicle is on inner junction edge
3565  distance = myLane->getLength() - getPositionOnLane();
3566  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
3567  }
3568  }
3569  return distance;
3570 }
3571 
3572 
3573 std::pair<const MSVehicle* const, double>
3574 MSVehicle::getLeader(double dist) const {
3575  if (myLane == 0) {
3576  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
3577  }
3578  if (dist == 0) {
3580  }
3581  const MSVehicle* lead = 0;
3582  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
3583  // vehicle might be outside the road network
3584  MSLane::VehCont::const_iterator it = std::find(vehs.begin(), vehs.end(), this);
3585  if (it != vehs.end() && it + 1 != vehs.end()) {
3586  lead = *(it + 1);
3587  }
3588  if (lead != 0) {
3589  std::pair<const MSVehicle* const, double> result(
3592  return result;
3593  }
3594  const double seen = myLane->getLength() - getPositionOnLane();
3595  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
3596  std::pair<const MSVehicle* const, double> result = myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
3598  return result;
3599 }
3600 
3601 
3602 double
3604  // calling getLeader with 0 would induce a dist calculation but we only want to look for the leaders on the current lane
3605  std::pair<const MSVehicle* const, double> leaderInfo = getLeader(-1);
3606  if (leaderInfo.first == 0 || getSpeed() == 0) {
3607  return -1;
3608  }
3609  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
3610 }
3611 
3612 
3613 double
3616 }
3617 
3618 
3619 double
3622 }
3623 
3624 
3625 double
3628 }
3629 
3630 
3631 double
3634 }
3635 
3636 
3637 double
3640 }
3641 
3642 
3643 double
3646 }
3647 
3648 
3649 double
3652 }
3653 
3654 
3655 double
3658 }
3659 
3660 
3661 void
3663  if (myPersonDevice == 0) {
3665  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
3666  }
3668  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
3669  int numExpected = (int) myStops.front().awaitedPersons.size();
3670  if (numExpected != 0) {
3671  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
3672  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
3673  // Bus drivers usually do not know the names of the passengers.
3674  myStops.front().awaitedPersons.erase(person->getID());
3675  numExpected = (int) myStops.front().awaitedPersons.size();
3676  }
3677  if (numExpected == 0) {
3678  myStops.front().duration = 0;
3679  }
3680  }
3681 }
3682 
3683 void
3685  if (myContainerDevice == 0) {
3687  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
3688  }
3689  myContainerDevice->addTransportable(container);
3690  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
3691  int numExpected = (int) myStops.front().awaitedContainers.size();
3692  if (numExpected != 0) {
3693  myStops.front().awaitedContainers.erase(container->getID());
3694  numExpected = (int) myStops.front().awaitedContainers.size();
3695  }
3696  if (numExpected == 0) {
3697  myStops.front().duration = 0;
3698  }
3699  }
3700 }
3701 
3702 
3703 void
3705  const bool isPerson = dynamic_cast<MSPerson*>(t) != 0;
3707  if (device != 0) {
3708  device->removeTransportable(t);
3709  }
3710 }
3711 
3712 
3713 const std::vector<MSTransportable*>&
3715  if (myPersonDevice == 0) {
3717  } else {
3719  }
3720 }
3721 
3722 
3723 const std::vector<MSTransportable*>&
3725  if (myContainerDevice == 0) {
3727  } else {
3729  }
3730 }
3731 
3732 
3733 int
3735  int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
3736  return boarded + myParameter->personNumber;
3737 }
3738 
3739 int
3741  int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
3742  return loaded + myParameter->containerNumber;
3743 }
3744 
3745 
3746 void
3749  int state = getLaneChangeModel().getOwnState();
3750  // do not set blinker for sublane changes or when blocked from changing to the right
3751  const bool blinkerManoeuvre = (((state & LCA_SUBLANE) == 0) && (
3752  (state & LCA_KEEPRIGHT) == 0 || (state & LCA_BLOCKED) == 0));
3753  if ((state & LCA_LEFT) != 0 && blinkerManoeuvre) {
3755  } else if ((state & LCA_RIGHT) != 0 && blinkerManoeuvre) {
3757  } else if (getLaneChangeModel().isChangingLanes()) {
3758  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
3760  } else {
3762  }
3763  } else {
3764  const MSLane* lane = getLane();
3765  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
3766  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (double) 7.) {
3767  switch ((*link)->getDirection()) {
3768  case LINKDIR_TURN:
3769  case LINKDIR_LEFT:
3770  case LINKDIR_PARTLEFT:
3772  break;
3773  case LINKDIR_RIGHT:
3774  case LINKDIR_PARTRIGHT:
3776  break;
3777  default:
3778  break;
3779  }
3780  }
3781  }
3782  if (myInfluencer != 0 && myInfluencer->getSignals() >= 0) {
3784  myInfluencer->setSignals(-1); // overwrite computed signals only once
3785  }
3786 }
3787 
3788 void
3790  if (currentTime % 1000 == 0) {
3793  } else {
3795  }
3796  }
3797 }
3798 
3799 
3800 int
3802  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
3803  return (int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
3804 }
3805 
3806 
3807 void
3808 MSVehicle::setTentativeLaneAndPosition(MSLane* lane, double pos, double posLat) {
3809  assert(lane != 0);
3810  myLane = lane;
3811  myState.myPos = pos;
3812  myState.myPosLat = posLat;
3814 }
3815 
3816 
3817 double
3819  return myState.myPosLat + 0.5 * myLane->getWidth() - 0.5 * getVehicleType().getWidth();
3820 }
3821 
3822 
3823 double
3825  return getCenterOnEdge(lane) - 0.5 * getVehicleType().getWidth();
3826 }
3827 
3828 
3829 double
3831  if (lane == 0 || &lane->getEdge() == &myLane->getEdge()) {
3832  return myLane->getRightSideOnEdge() + myState.myPosLat + 0.5 * myLane->getWidth();
3833  } else {
3834  assert(myFurtherLanes.size() == myFurtherLanesPosLat.size());
3835  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3836  if (myFurtherLanes[i] == lane) {
3837 #ifdef DEBUG_FURTHER
3838  if (DEBUG_COND) std::cout << " getCenterOnEdge veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " furtherLat=" << myFurtherLanesPosLat[i]
3839  << " result=" << lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth()
3840  << "\n";
3841 #endif
3842  return lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth();
3843  }
3844  }
3845  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3846  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3847  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3848  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
3849  if (shadowFurther[i] == lane) {
3850  assert(getLaneChangeModel().getShadowLane() != 0);
3851  return (lane->getRightSideOnEdge() + getLaneChangeModel().getShadowFurtherLanesPosLat()[i] + 0.5 * lane->getWidth()
3853  }
3854  }
3855  assert(false);
3856  throw ProcessError("Request lateral pos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3857  }
3858 }
3859 
3860 
3861 double
3862 MSVehicle::getLatOffset(const MSLane* lane) const {
3863  assert(lane != 0);
3864  if (&lane->getEdge() == &myLane->getEdge()) {
3865  return myLane->getRightSideOnEdge() - lane->getRightSideOnEdge();
3866  } else {
3867  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3868  if (myFurtherLanes[i] == lane) {
3869 #ifdef DEBUG_FURTHER
3870  if (DEBUG_COND) {
3871  std::cout << " getLatOffset veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " posLat=" << myState.myPosLat << " furtherLat=" << myFurtherLanesPosLat[i] << "\n";
3872  }
3873 #endif
3875  }
3876  }
3877 #ifdef DEBUG_FURTHER
3878  if (DEBUG_COND) {
3879  std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3880  }
3881 #endif
3882  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3883  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3884  if (shadowFurther[i] == lane) {
3885 #ifdef DEBUG_FURTHER
3886  if (DEBUG_COND) std::cout << " getLatOffset veh=" << getID()
3887  << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
3888  << " lane=" << lane->getID()
3889  << " i=" << i
3890  << " posLat=" << myState.myPosLat
3891  << " shadowPosLat=" << getLatOffset(getLaneChangeModel().getShadowLane())
3892  << " shadowFurtherLat=" << getLaneChangeModel().getShadowFurtherLanesPosLat()[i]
3893  << "\n";
3894 #endif
3896  }
3897  }
3898  assert(false);
3899  throw ProcessError("Request lateral offset of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3900  }
3901 }
3902 
3903 
3904 double
3905 MSVehicle::getLateralOverlap(double posLat) const {
3906  return (fabs(posLat) + 0.5 * getVehicleType().getWidth()
3907  - 0.5 * myLane->getWidth());
3908 }
3909 
3910 
3911 double
3914 }
3915 
3916 void
3918  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
3919  if ((*i).myLink != 0) {
3920  (*i).myLink->removeApproaching(this);
3921  }
3922  }
3923  // unregister on all shadow links
3925 }
3926 
3927 
3928 bool
3930  // the following links are unsafe:
3931  // - zipper links if they are close enough and have approaching vehicles in the relevant time range
3932  // - unprioritized links if the vehicle is currently approaching a prioritzed link and unable to stop in time
3933  double seen = myLane->getLength() - getPositionOnLane();
3934  const double dist = getCarFollowModel().brakeGap(getSpeed(), getCarFollowModel().getMaxDecel(), 0);
3935  if (seen < dist) {
3936  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(lane);
3937  int view = 1;
3938  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3939  DriveItemVector::const_iterator di = myLFLinkLanes.begin();
3940  while (!lane->isLinkEnd(link) && seen <= dist) {
3941  if (!lane->getEdge().isInternal()
3942  && (((*link)->getState() == LINKSTATE_ZIPPER && seen < MSLink::ZIPPER_ADAPT_DIST)
3943  || !(*link)->havePriority())) {
3944  // find the drive item corresponding to this link
3945  bool found = false;
3946  while (di != myLFLinkLanes.end() && !found) {
3947  if ((*di).myLink != 0) {
3948  const MSLane* diPredLane = (*di).myLink->getLaneBefore();
3949  if (diPredLane != 0) {
3950  if (&diPredLane->getEdge() == &lane->getEdge()) {
3951  found = true;
3952  }
3953  }
3954  }
3955  if (!found) {
3956  di++;
3957  }
3958  }
3959  if (found) {
3960  const SUMOTime leaveTime = (*link)->getLeaveTime((*di).myArrivalTime, (*di).myArrivalSpeed,
3961  (*di).getLeaveSpeed(), getVehicleType().getLength());
3962  if ((*link)->hasApproachingFoe((*di).myArrivalTime, leaveTime, (*di).myArrivalSpeed, getCarFollowModel().getMaxDecel())) {
3963  //std::cout << SIMTIME << " veh=" << getID() << " aborting changeTo=" << Named::getIDSecure(bestLaneConts.front()) << " linkState=" << toString((*link)->getState()) << " seen=" << seen << " dist=" << dist << "\n";
3964  return true;
3965  }
3966  }
3967  // no drive item is found if the vehicle aborts it's request within dist
3968  }
3969  lane = (*link)->getViaLaneOrLane();
3970  if (!lane->getEdge().isInternal()) {
3971  view++;
3972  }
3973  seen += lane->getLength();
3974  link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3975  }
3976  }
3977  return false;
3978 }
3979 
3980 
3983  PositionVector centerLine;
3984  centerLine.push_back(getPosition());
3985  centerLine.push_back(getBackPosition());
3986  centerLine.move2side(0.5 * myType->getWidth());
3987  PositionVector result = centerLine;
3988  centerLine.move2side(-myType->getWidth());
3989  result.append(centerLine.reverse(), POSITION_EPS);
3990  return result;
3991 }
3992 
3993 
3996  // XXX implement more types
3997  switch (myType->getGuiShape()) {
3998  case SVS_PASSENGER:
3999  case SVS_PASSENGER_SEDAN:
4001  case SVS_PASSENGER_WAGON:
4002  case SVS_PASSENGER_VAN: {
4003  PositionVector result;
4004  PositionVector centerLine;
4005  centerLine.push_back(getPosition());
4006  centerLine.push_back(getBackPosition());
4007  PositionVector line1 = centerLine;
4008  PositionVector line2 = centerLine;
4009  line1.move2side(0.3 * myType->getWidth());
4010  line2.move2side(0.5 * myType->getWidth());
4011  line2.scaleRelative(0.8);
4012  result.push_back(line1[0]);
4013  result.push_back(line2[0]);
4014  result.push_back(line2[1]);
4015  result.push_back(line1[1]);
4016  line1.move2side(-0.6 * myType->getWidth());
4017  line2.move2side(-1.0 * myType->getWidth());
4018  result.push_back(line1[1]);
4019  result.push_back(line2[1]);
4020  result.push_back(line2[0]);
4021  result.push_back(line1[0]);
4022  return result;
4023  }
4024  default:
4025  return getBoundingBox();
4026  }
4027 }
4028 
4029 
4030 bool
4031 MSVehicle::onFurtherEdge(const MSEdge* edge) const {
4032  for (std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
4033  if (&(*i)->getEdge() == edge) {
4034  return true;
4035  }
4036  }
4037  return false;
4038 }
4039 
4040 
4041 #ifndef NO_TRACI
4042 bool
4043 MSVehicle::addTraciStop(MSLane* const lane, const double startPos, const double endPos, const SUMOTime duration, const SUMOTime until,
4044  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
4045  //if the stop exists update the duration
4046  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
4047  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
4048  if (duration == 0 && !iter->reached) {
4049  myStops.erase(iter);
4050  updateBestLanes(true);
4051  } else {
4052  iter->duration = duration;
4053  }
4054  return true;
4055  }
4056  }
4057 
4059  newStop.lane = lane->getID();
4060  newStop.startPos = startPos;
4061  newStop.endPos = endPos;
4062  newStop.duration = duration;
4063  newStop.until = until;
4064  newStop.triggered = triggered;
4065  newStop.containerTriggered = containerTriggered;
4066  newStop.parking = parking;
4067  newStop.index = STOP_INDEX_FIT;
4068  const bool result = addStop(newStop, errorMsg);
4069  if (result) {
4070  myParameter->stops.push_back(newStop);
4071  }
4072  if (myLane != 0) {
4073  updateBestLanes(true);
4074  }
4075  return result;
4076 }
4077 
4078 
4079 bool
4080 MSVehicle::addTraciStopAtStoppingPlace(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
4081  const bool triggered, const bool containerTriggered, const SumoXMLTag stoppingPlaceType, std::string& errorMsg) {
4082  //if the stop exists update the duration
4083  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
4084  Named* stop = 0;
4085  switch (stoppingPlaceType) {
4086  case SUMO_TAG_BUS_STOP:
4087  stop = iter->busstop;
4088  break;
4090  stop = iter->containerstop;
4091  break;
4093  stop = iter->chargingStation;
4094  break;
4095  case SUMO_TAG_PARKING_AREA:
4096  stop = iter->parkingarea;
4097  break;
4098  default:
4099  throw ProcessError("Invalid Stopping place type '" + toString(stoppingPlaceType) + "'");
4100  }
4101  if (stop != 0 && stop->getID() == stopId) {
4102  if (duration == 0 && !iter->reached) {
4103  myStops.erase(iter);
4104  } else {
4105  iter->duration = duration;
4106  }
4107  return true;
4108  }
4109  }
4110 
4112  MSStoppingPlace* bs = 0;
4113  switch (stoppingPlaceType) {
4114  case SUMO_TAG_BUS_STOP:
4115  newStop.busstop = stopId;
4116  bs = MSNet::getInstance()->getBusStop(stopId);
4117  if (bs == 0) {
4118  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
4119  return false;
4120  }
4121  break;
4123  newStop.containerstop = stopId;
4124  bs = MSNet::getInstance()->getContainerStop(stopId);
4125  if (bs == 0) {
4126  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
4127  return false;
4128  }
4129  break;
4131  newStop.chargingStation = stopId;
4132  bs = MSNet::getInstance()->getChargingStation(stopId);
4133  if (bs == 0) {
4134  errorMsg = "The charging station '" + stopId + "' is not known for vehicle '" + getID() + "'";
4135  return false;
4136  }
4137  break;
4138  case SUMO_TAG_PARKING_AREA:
4139  newStop.parkingarea = stopId;
4140  bs = MSNet::getInstance()->getParkingArea(stopId);
4141  if (bs == 0) {
4142  errorMsg = "The parking area '" + stopId + "' is not known for vehicle '" + getID() + "'";
4143  return false;
4144  }
4145  break;
4146  default:
4147  throw ProcessError("Invalid Stopping place type '" + toString(stoppingPlaceType) + "'");
4148  }
4149  newStop.duration = duration;
4150  newStop.until = until;
4151  newStop.triggered = triggered;
4152  newStop.containerTriggered = containerTriggered;
4153  newStop.parking = parking;
4154  newStop.index = STOP_INDEX_FIT;
4155  newStop.lane = bs->getLane().getID();
4156  newStop.endPos = bs->getEndLanePosition();
4157  newStop.startPos = bs->getBeginLanePosition();
4158  const bool result = addStop(newStop, errorMsg);
4159  if (result) {
4160  myParameter->stops.push_back(newStop);
4161  }
4162  if (myLane != 0) {
4163  updateBestLanes(true);
4164  }
4165  return result;
4166 }
4167 
4168 
4169 bool
4171  if (isStopped()) {
4175  }
4179  }
4180  // we have waited long enough and fulfilled any passenger-requirements
4181  if (myStops.front().busstop != 0) {
4182  // inform bus stop about leaving it
4183  myStops.front().busstop->leaveFrom(this);
4184  }
4185  // we have waited long enough and fulfilled any container-requirements
4186  if (myStops.front().containerstop != 0) {
4187  // inform container stop about leaving it
4188  myStops.front().containerstop->leaveFrom(this);
4189  }
4190  if (myStops.front().parkingarea != 0) {
4191  // inform parking area about leaving it
4192  myStops.front().parkingarea->leaveFrom(this);
4193  }
4194  // the current stop is no longer valid
4196  if (MSStopOut::active()) {
4197  MSStopOut::getInstance()->stopEnded(this, myStops.front());
4198  }
4199  if (myStops.front().collision && MSLane::getCollisionAction() == MSLane::COLLISION_ACTION_WARN) {
4200  myCollisionImmunity = TIME2STEPS(5); // leave the conflict area
4201  }
4202  myStops.pop_front();
4203  // do not count the stopping time towards gridlock time.
4204  // Other outputs use an independent counter and are not affected.
4205  myWaitingTime = 0;
4206  // maybe the next stop is on the same edge; let's rebuild best lanes
4207  updateBestLanes(true);
4208  // continue as wished...
4210  return true;
4211  }
4212  return false;
4213 }
4214 
4215 
4218  return myStops.front();
4219 }
4220 
4221 
4224  if (myInfluencer == 0) {
4225  myInfluencer = new Influencer();
4226  }
4227  return *myInfluencer;
4228 }
4229 
4230 
4231 const MSVehicle::Influencer*
4233  return myInfluencer;
4234 }
4235 
4236 
4237 double
4239  if (myInfluencer != 0 && myInfluencer->getOriginalSpeed() != -1) {
4240  return myInfluencer->getOriginalSpeed();
4241  }
4242  return myState.mySpeed;
4243 }
4244 
4245 
4246 int
4248  if (hasInfluencer()) {
4250  MSNet::getInstance()->getCurrentTimeStep(),
4251  myLane->getEdge(),
4252  getLaneIndex(),
4253  state);
4254  }
4255  return state;
4256 }
4257 
4258 
4259 void
4261  myCachedPosition = xyPos;
4262 }
4263 
4264 #endif
4265 
4266 bool
4268  return myInfluencer != 0 && myInfluencer->isVTDControlled();
4269 }
4270 
4271 
4272 bool
4275 }
4276 
4277 
4278 void
4280  // lots of duplication with SUMOVehicleParameter::Stop::write()
4281  dev.openTag(SUMO_TAG_STOP);
4282  if (busstop != 0) {
4283  dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop->getID());
4284  }
4285  if (containerstop != 0) {
4286  dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop->getID());
4287  }
4288  if (busstop == 0 && containerstop == 0) {
4289  dev.writeAttr(SUMO_ATTR_LANE, lane->getID());
4290  dev.writeAttr(SUMO_ATTR_STARTPOS, startPos);
4291  dev.writeAttr(SUMO_ATTR_ENDPOS, endPos);
4292  }
4293  if (duration >= 0) {
4294  dev.writeAttr(SUMO_ATTR_DURATION, STEPS2TIME(duration));
4295  }
4296  if (until >= 0) {
4297  dev.writeAttr(SUMO_ATTR_UNTIL, STEPS2TIME(until));
4298  }
4299  if (triggered) {
4300  dev.writeAttr(SUMO_ATTR_TRIGGERED, triggered);
4301  }
4302  if (containerTriggered) {
4303  dev.writeAttr(SUMO_ATTR_CONTAINER_TRIGGERED, containerTriggered);
4304  }
4305  if (parking) {
4306  dev.writeAttr(SUMO_ATTR_PARKING, parking);
4307  }
4308  if (awaitedPersons.size() > 0) {
4309  dev.writeAttr(SUMO_ATTR_EXPECTED, joinToString(awaitedPersons, " "));
4310  }
4311  if (awaitedContainers.size() > 0) {
4312  dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, joinToString(awaitedContainers, " "));
4313  }
4314  dev.closeTag();
4315 }
4316 
4317 
4318 double
4320  if (busstop != 0) {
4321  return busstop->getLastFreePos(veh);
4322  } else if (containerstop != 0) {
4323  return containerstop->getLastFreePos(veh);
4324  } else if (parkingarea != 0) {
4325  return parkingarea->getLastFreePos(veh);
4326  } else if (chargingStation != 0) {
4327  return chargingStation->getLastFreePos(veh);
4328  }
4329  return endPos;
4330 }
4331 
4332 
4333 bool
4334 MSVehicle::keepClear(const MSLink* link) const {
4335  if (link->hasFoes() && link->keepClear() /* && item.myLink->willHaveBlockedFoe()*/) {
4336  const double keepClearTime = getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_IGNORE_KEEPCLEAR_TIME, -1);
4337  //std::cout << SIMTIME << " veh=" << getID() << " keepClearTime=" << keepClearTime << " accWait=" << getAccumulatedWaitingSeconds() << " keepClear=" << (keepClearTime < 0 || getAccumulatedWaitingSeconds() < keepClearTime) << "\n";
4338  return keepClearTime < 0 || getAccumulatedWaitingSeconds() < keepClearTime;
4339  } else {
4340  return false;
4341  }
4342 }
4343 
4344 
4345 bool
4346 MSVehicle::ignoreRed(const MSLink* link, bool canBrake) const {
4348  return true;
4349  }
4350  const double ignoreRedTime = getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME, -1);
4351 #ifdef DEBUG_IGNORE_RED
4352  if (DEBUG_COND) {
4353  std::cout << SIMTIME << " veh=" << getID() << " link=" << link->getViaLaneOrLane()->getID() << " state=" << toString(link->getState()) << "\n";
4354  }
4355 #endif
4356  if (ignoreRedTime < 0) {
4357  return false;
4358  } else if (link->haveYellow()) {
4359  // always drive at yellow when ignoring red
4360  return true;
4361  } else if (link->haveRed()) {
4362  assert(link->getTLLogic() != 0);
4363  const double redDuration = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - link->getLastStateChange());
4364 #ifdef DEBUG_IGNORE_RED
4365  if (DEBUG_COND) {
4366  std::cout
4367  // << SIMTIME << " veh=" << getID() << " link=" << link->getViaLaneOrLane()->getID()
4368  << " ignoreRedTime=" << ignoreRedTime
4369  << " spentRed=" << redDuration
4370  << " canBrake=" << canBrake << "\n";
4371  }
4372 #endif
4373  // when activating ignoreRed behavior, vehicles will always drive if they cannot brake
4374  return !canBrake || ignoreRedTime > redDuration;
4375  } else {
4376  return false;
4377  }
4378 }
4379 
4380 
4381 void
4384  // here starts the vehicle internal part (see loading)
4385  std::vector<std::string> internals;
4386  internals.push_back(toString(myDeparture));
4387  internals.push_back(toString(distance(myRoute->begin(), myCurrEdge)));
4388  internals.push_back(toString(myDepartPos));
4389  internals.push_back(toString(myWaitingTime));
4390  out.writeAttr(SUMO_ATTR_STATE, internals);
4394  // save stops and parameters
4395  for (std::list<Stop>::const_iterator it = myStops.begin(); it != myStops.end(); ++it) {
4396  it->write(out);
4397  }
4398  myParameter->writeParams(out);
4399  for (std::vector<MSDevice*>::const_iterator dev = myDevices.begin(); dev != myDevices.end(); ++dev) {
4400  (*dev)->saveState(out);
4401  }
4402  out.closeTag();
4403 }
4404 
4405 
4406 void
4407 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
4408  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
4409  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
4410  }
4411  int routeOffset;
4412  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
4413  bis >> myDeparture;
4414  bis >> routeOffset;
4415  bis >> myDepartPos;
4416  bis >> myWaitingTime;
4417  if (hasDeparted()) {
4418  myCurrEdge += routeOffset;
4419  myDeparture -= offset;
4420  }
4424  // no need to reset myCachedPosition here since state loading happens directly after creation
4425 }
4426 
4427 
4428 /****************************************************************************/
double myPos
the stored position
Definition: MSVehicle.h:140
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:33
double myLatDist
The requested lateral change.
Definition: MSVehicle.h:1388
A lane area vehicles can halt at.
Definition: MSParkingArea.h:66
void setAngle(double angle)
Set a custom vehicle angle in rad.
Definition: MSVehicle.cpp:929
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:1156
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1543
int getCapacity() const
Returns the area capacity.
The link is a partial left direction.
int getOccupancy() const
Returns the area occupancy.
bool isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
Definition: MSVehicle.cpp:4267
double getMinGap() const
Get the free space in front of vehicles of this class.
static double gLateralResolution
Definition: MSGlobals.h:92
#define DIST2SPEED(x)
Definition: SUMOTime.h:57
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:261
static bool active()
Definition: MSStopOut.h:64
SumoXMLTag
Numbers representing SUMO-XML - element names.
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:2951
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:582
static int nextLinkPriority(const std::vector< MSLane * > &conts)
get a numerical value for the priority of the upcoming link
Definition: MSVehicle.cpp:3469
std::pair< MSVehicle *const, double > getLeaderOnConsecutive(double dist, double seen, double speed, const MSVehicle &veh, const std::vector< MSLane * > &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:2012
double posLat() const
Lateral Position of this state (m relative to the centerline of the lane).
Definition: MSVehicle.h:123
double myAngle
the angle in radians (
Definition: MSVehicle.h:1591
double getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:500
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1663
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1702
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:854
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1730
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
virtual int addLeader(const MSVehicle *veh, bool beyond, double latOffset=0)
int getVehicleNumber() const
Returns the number of vehicles on this lane (for which this lane is responsible)
Definition: MSLane.h:352
virtual std::string toString() const
print a debugging representation
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
void remove(MSVehicle *veh)
Remove a vehicle from this transfer object.
double getCenterOnEdge() const
Definition: MSLane.h:943
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:1739
MoveReminderCont myMoveReminders
Currently relevant move reminders.
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:1542
double getMaxSpeed() const
Returns the maximum speed.
std::string containerstop
(Optional) container stop if one is assigned to the stop
const MSEdge * getNextNormal() const
Returns the lane&#39;s follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1525
LaneChangeMode
modes for resolving conflicts between external control (traci) and vehicle control over lane changing...
Definition: MSVehicle.h:1112
void enterLaneAtInsertion(MSLane *enteredLane, double pos, double speed, double posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:3039
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1540
void append(const PositionVector &v, double sameThreshold=2.0)
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1580
LaneChangeMode myRightDriveLC
changing to the rightmost lane
Definition: MSVehicle.h:1426
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
Definition: MSPModel.h:91
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1550
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:406
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:796
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:1786
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1573
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1535
MSParkingArea * getParkingArea(const std::string &id) const
Returns the named parking area.
Definition: MSNet.cpp:911
void adaptToLeaders(const MSLeaderInfo &ahead, double latOffset, const double seen, DriveProcessItem *const lastLink, const MSLane *const lane, double &v, double &vLinkPass) const
Definition: MSVehicle.cpp:1933
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
double myOriginalSpeed
The velocity before influence.
Definition: MSVehicle.h:1385
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const =0
Computes the vehicle&#39;s follow speed (no dawdling)
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:61
Stop & getNextStop()
Definition: MSVehicle.cpp:4217
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
Definition: MSLane.cpp:2957
virtual double moveHelper(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences.
Definition: MSCFModel.cpp:153
A lane area vehicles can halt at.
bool replaceParkingArea(MSParkingArea *parkingArea, std::string &errorMsg)
replace the current parking area stop with a new stop with merge duration
Definition: MSVehicle.cpp:1156
void enter(SUMOVehicle *what, double beg, double end)
Called if a vehicle enters this stop.
DriveItemVector myLFLinkLanes
Definition: MSVehicle.h:1656
bool resumeFromStopping()
Definition: MSVehicle.cpp:4170
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1583
bool hasInfluencer() const
Definition: MSVehicle.h:1451
SUMOTime duration
The stopping duration.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:168
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
SUMOTime myLastVTDAccess
Definition: MSVehicle.h:1415
The speed is given.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:725
double getTimeGapOnLane() const
Returns the time gap in seconds to the leader of the vehicle on the same lane.
Definition: MSVehicle.cpp:3603
void setBlinkerInformation()
Definition: MSVehicle.cpp:3747
double getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane...
Definition: MSVehicle.cpp:3862
int getLanechangeMode() const
return the current lane change mode
Definition: MSVehicle.cpp:290
const MSLeaderInfo & getLastVehicleInformation(const MSVehicle *ego, double latOffset, double minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:939
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2917
bool isStoppedOnLane() const
Definition: MSVehicle.cpp:1245
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:3684
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
Definition: MSVehicle.cpp:3929
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:322
The vehicle arrived at a junction.
bool isVTDControlled() const
Definition: MSVehicle.cpp:466
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:547
double implicitDeltaPosVTD(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new VTD position ...
Definition: MSVehicle.cpp:527
int myRoutingMode
routing mode (see TraCIConstants.h)
Definition: MSVehicle.h:1437
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
void enter(SUMOVehicle *what, double beg, double end)
Called if a vehicle enters this stop.
const double SUMO_const_laneWidth
Definition: StdDefs.h:50
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:636
void planMove(const SUMOTime t, const MSLeaderInfo &ahead, const double lengthsInFront)
Compute safe velocities for the upcoming lanes based on positions and speeds from the last time step...
Definition: MSVehicle.cpp:1506
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:60
double maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:604
bool myConsiderMaxAcceleration
Whether the maximum acceleration shall be regarded.
Definition: MSVehicle.h:1397
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:65
#define INVALID
double myPosLat
the stored lateral position
Definition: MSVehicle.h:146
int getShadowDirection() const
return the direction in which the current shadow lane lies
double myArrivalPos
The position on the destination lane where the vehicle stops.
The link is a 180 degree turn.
virtual void clear()
discard all information
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
Wants go to the right.
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1849
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1564
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:442
#define STOPPING_PLACE_OFFSET
Definition: MSVehicle.cpp:99
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:1241
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:448
double getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:3614
lane can change or stay
bool addTraciStopAtStoppingPlace(const std::string &stopId, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, const SumoXMLTag stoppingPlaceType, std::string &errorMsg)
Definition: MSVehicle.cpp:4080
bool myRespectJunctionPriority
Whether the junction priority rules are respected.
Definition: MSVehicle.h:1403
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:848
const MSLane * getBackLane() const
Definition: MSVehicle.cpp:2551
virtual double getHeadwayTime() const
Get the driver&#39;s desired headway [s].
Definition: MSCFModel.h:247
void registerEmergencyStop()
register emergency stop
MSChargingStation * getChargingStation(const std::string &id) const
Returns the named charging station.
Definition: MSNet.cpp:934
State & operator=(const State &state)
Assignment operator.
Definition: MSVehicle.cpp:130
double getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:484
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:169
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0, bool addStops=true)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:645
T MAX2(T a, T b)
Definition: StdDefs.h:74
double getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
const MSRoute & getRoute() const
Returns the current route.
vehicle doesn&#39;t want to change
Definition: MSVehicle.h:224
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:1120
double getSpaceTillLastStanding(const MSLane *l, bool &foundStopped) const
Definition: MSVehicle.cpp:2685
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:806
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
void write(OutputDevice &dev) const
Definition: MSVehicle.cpp:4279
double slopeDegreeAtOffset(double pos) const
Returns the slope at the given length.
const MSRoute * myRoute
This vehicle&#39;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
double getEndLanePosition() const
Returns the end position of this stop.
const std::string & getID() const
returns the id of the transportable
double getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:3626
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
void postProcessVTD(MSVehicle *v)
Definition: MSVehicle.cpp:477
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:375
SUMOTime until
The time at which the vehicle may continue its journey.
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false, MSRouteIterator *searchStart=0)
Adds a stop.
Definition: MSVehicle.cpp:1000
void adaptBestLanesOccupation(int laneIndex, double density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:3541
WaitingTimeCollector myWaitingTimeCollector
Definition: MSVehicle.h:1529
const int STOP_INDEX_FIT
void checkRewindLinkLanes(const double lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:2706
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:820
This is an uncontrolled, right-before-left link.
render as a sedan passenger vehicle ("Stufenheck")
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:2086
int getLaneIndex() const
Definition: MSVehicle.cpp:3801
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
static double computeNoise(SUMOEmissionClass c, double v, double a)
Returns the noise produced by the a vehicle of the given type at the given speed. ...
SUMOTime myMemorySize
the maximal memory to store
Definition: MSVehicle.h:207
void setVTDControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:453
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
bool isInternal() const
Definition: MSLane.cpp:1679
int myArrivalLane
The destination lane where the vehicle stops.
const SUMOVehicleParameter * myParameter
This vehicle&#39;s parameter.
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
double getMinimalArrivalSpeed(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance.
Definition: MSCFModel.cpp:374
double myLastCoveredDist
Definition: MSVehicle.h:160
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:356
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:56
#define TS
Definition: SUMOTime.h:52
double computeAngle() const
compute the current vehicle angle
Definition: MSVehicle.cpp:935
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1588
A storage for edge travel times and efforts.
virtual double getFloat(int id) const =0
Returns the double-value of the named (by its enum-value) attribute.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:252
double nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:723
double getLength() const
Returns the vehicle&#39;s length.
double length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:717
Wants go to the left.
double getLastFreePos(const SUMOVehicle &forVehicle) const
Returns the last free position on this stop.
This is an uncontrolled, all-way stop link.
The action is due to the wish to be faster (tactical lc)
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:63
#define abs(a)
Definition: polyfonts.c:67
used by the sublane model
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:2989
bool collision
Whether this stop was triggered by a collision.
Definition: MSVehicle.h:858
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
std::string parkingarea
(Optional) parking area if one is assigned to the stop
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The simulated network and simulation perfomer.
Definition: MSNet.h:89
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false, bool check=false, bool addStops=true)
Replaces the current route by the given edges.
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:73
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:842
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
WaitingTimeCollector(SUMOTime memory=MSGlobals::gWaitingTimeMemory)
Constructor.
Definition: MSVehicle.cpp:161
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:3144
SUMOTime getMinimalArrivalTime(double dist, double currentSpeed, double arrivalSpeed) const
Computes the minimal time needed to cover a distance given the desired speed at arrival.
Definition: MSCFModel.cpp:320
#define SIMTIME
Definition: SUMOTime.h:70
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1742
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:379
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:37
The lane is given.
double backPos() const
back Position of this state
Definition: MSVehicle.h:128
Right blinker lights are switched on.
Definition: MSVehicle.h:1078
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2926
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
MSChargingStation * chargingStation
(Optional) charging station if one is assigned to the stop
Definition: MSVehicle.h:832
double getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:4238
PositionVector reverse() const
reverse position vector
double getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MSVehicle.cpp:795
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:775
static CollisionAction getCollisionAction()
Definition: MSLane.h:1043
The vehicles starts to stop.
Definition: MSNet.h:589
void unregisterOneWaitingForContainer()
decreases the count of vehicles waiting for a container to allow recogniztion of container related de...
SUMOTime getMemorySize() const
Definition: MSVehicle.h:196
Needs to stay on the current lane.
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
std::vector< std::pair< SUMOTime, int > > myLaneTimeLine
The lane usage time line to apply.
Definition: MSVehicle.h:1382
double influenceSpeed(SUMOTime currentTime, double speed, double vSafe, double vMin, double vMax)
Applies stored velocity information on the speed to use.
Definition: MSVehicle.cpp:301
The state of a link.
double getImpatience() const
Returns this vehicles impatience.
int getContainerNumber() const
Returns the number of containers.
Definition: MSVehicle.cpp:3740
std::vector< double > myFurtherLanesPosLat
Definition: MSVehicle.h:1574
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
WaitingTimeCollector & operator=(const WaitingTimeCollector &wt)
Assignment operator.
Definition: MSVehicle.cpp:166
std::string busstop
(Optional) bus stop if one is assigned to the stop
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:142
static std::vector< MSTransportable * > myEmptyTransportableVector
Definition: MSVehicle.h:1558
void adaptToLeader(const std::pair< const MSVehicle *, double > leaderInfo, const double seen, DriveProcessItem *const lastLink, const MSLane *const lane, double &v, double &vLinkPass, double distToCrossing=-1) const
Definition: MSVehicle.cpp:1978
double departSpeed
(optional) The initial speed of the vehicle
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:81
void leaveLane(const MSMoveReminder::Notification reason, const MSLane *approachedLane=0)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:3094
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, double > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:263
The vehicle changes lanes (micro only)
double getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:874
double getElectricityConsumption() const
Returns electricity consumption of the current state.
Definition: MSVehicle.cpp:3650
double getLeaveSpeed() const
Definition: MSVehicle.h:1649
MSLane * lane
The described lane.
Definition: MSVehicle.h:715
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
Definition: MSVehicle.cpp:432
Left blinker lights are switched on.
Definition: MSVehicle.h:1080
double myDepartPos
The real depart position.
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2161
#define max(a, b)
Definition: polyfonts.c:65
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
const MSLane & getLane() const
Returns the lane this stop is located at.
double getBackPositionOnLane() const
Get the vehicle&#39;s position relative to its current lane.
Definition: MSVehicle.h:399
void setSublaneChange(double latDist)
Sets a new sublane-change request.
Definition: MSVehicle.cpp:275
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:714
double getLastFreePos(const SUMOVehicle &forVehicle) const
Returns the last free position on this stop.
blocked in all directions
The vehicle got a new route.
Definition: MSNet.h:583
double getDistanceToPosition(double destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:3557
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:864
vehicle want&#39;s to change to right lane
Definition: MSVehicle.h:228
const SUMOVTypeParameter & getParameter() const
void updateState(double vNext)
updates the vehicles state, given a next value for its speed. This value can be negative in case of t...
Definition: MSVehicle.cpp:2504
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:104
void removeApproachingInformation(DriveItemVector &lfLinks) const
unregister approach from all upcoming links
Definition: MSVehicle.cpp:3917
Position getPositionAlongBestLanes(double offset) const
Return the (x,y)-position, which the vehicle would reach if it continued along its best continuation ...
Definition: MSVehicle.cpp:838
The action is urgent (to be defined by lc-model)
Representation of a vehicle.
Definition: SUMOVehicle.h:67
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:828
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:168
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3982
double startPos
The stopping position start.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Encapsulated SAX-Attributes.
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
static MSPModel * getModel()
Definition: MSPModel.cpp:66
SUMOTime myCollisionImmunity
amount of time for which the vehicle is immune from collisions
Definition: MSVehicle.h:1597
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:767
bool keepStopping(bool afterProcessing=false) const
Returns whether the vehicle is stopped and must continue to do so.
Definition: MSVehicle.cpp:1250
void adaptLeaveSpeed(const double v)
Definition: MSVehicle.h:1642
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:212
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:222
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:3502
std::string chargingStation
(Optional) charging station if one is assigned to the stop
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
TraciLaneChangePriority myTraciLaneChangePriority
flags for determining the priority of traci lane change requests
Definition: MSVehicle.h:1431
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:701
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:3162
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:784
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:856
Position myCachedPosition
Definition: MSVehicle.h:1599
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:305
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:1867
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:824
double currentLength
The length which may be driven on this lane.
Definition: MSVehicle.h:719
const std::vector< MSLane * > & getShadowFurtherLanes() const
bool triggered
whether an arriving person lets the vehicle continue
std::list< Stop > myStops
The vehicle&#39;s list of stops.
Definition: MSVehicle.h:1561
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
const int STOP_INDEX_END
SUMOTime myTimeLoss
the time loss due to writing with less than maximum speed
Definition: MSVehicle.h:1532
void getSubLanes(const MSVehicle *veh, double latOffset, int &rightmost, int &leftmost) const
void removeVType(const MSVehicleType *vehType)
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3995
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:1240
SUMOTime collisionStopTime() const
Returns the remaining time a vehicle needs to stop due to a collision. A negative value indicates tha...
Definition: MSVehicle.cpp:1260
bool myConsiderMaxDeceleration
Whether the maximum deceleration shall be regarded.
Definition: MSVehicle.h:1400
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1538
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:1311
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition) ...
Definition: MSVehicle.h:1586
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...
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:1746
void resetRoutePosition(int index)
Definition: MSVehicle.cpp:713
const std::vector< MSTransportable * > & getContainers() const
retrieve riding containers
Definition: MSVehicle.cpp:3724
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1555
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:128
double getDeltaPos(double accel)
calculates the distance covered in the next integration step given an acceleration and assuming the c...
Definition: MSVehicle.cpp:2064
double getSafeFollowSpeed(const std::pair< const MSVehicle *, double > leaderInfo, const double seen, const MSLane *const lane, double distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:2044
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:911
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:838
double getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:3638
bool isRoundabout() const
Definition: MSEdge.h:620
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:372
T MIN2(T a, T b)
Definition: StdDefs.h:68
double updateFurtherLanes(std::vector< MSLane * > &furtherLanes, std::vector< double > &furtherLanesPosLat, const std::vector< MSLane * > &passedLanes)
update a vector of further lanes and return the new backPos
Definition: MSVehicle.cpp:2561
The link is a (hard) right direction.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT() const
Definition: MSVehicle.cpp:543
The action is needed to follow the route (navigational lc)
#define POSITION_EPS
Definition: config.h:176
The brake lights are on.
Definition: MSVehicle.h:1084
void addTransportable(MSTransportable *transportable)
Add a passenger.
A blue emergency light is on.
Definition: MSVehicle.h:1100
double speed() const
Speed of this state.
Definition: MSVehicle.h:118
A structure representing the best lanes for continuing the current route starting at &#39;lane&#39;...
Definition: MSVehicle.h:713
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:4407
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:627
void stopStarted(const SUMOVehicle *veh, int numPersons, int numContainers)
Definition: MSStopOut.cpp:64
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:2617
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0 ...
Definition: MSPModel.h:97
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:219
double getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3830
double myStopDist
distance to the next stop or -1 if there is none
Definition: MSVehicle.h:1594
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: MSVehicle.h:852
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:76
bool keepClear(const MSLink *link) const
decide whether the given link must be kept clear
Definition: MSVehicle.cpp:4334
double endPos
The stopping position end.
render as a van
int getSignals() const
Definition: MSVehicle.h:1367
const std::vector< double > & getShadowFurtherLanesPosLat() const
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:338
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
double myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1570
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:3549
#define DEG2RAD(x)
Definition: GeomHelper.h:45
double getRightSideOnLane() const
Get the vehicle&#39;s lateral position on the lane:
Definition: MSVehicle.cpp:3818
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
double myPreviousSpeed
the speed at the begin of the previous time step
Definition: MSVehicle.h:154
render as a passenger vehicle
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
MSParkingArea * parkingarea
(Optional) parkingArea if one is assigned to the stop
Definition: MSVehicle.h:830
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1525
LaneChangeMode mySpeedGainLC
lane changing to travel with higher speed
Definition: MSVehicle.h:1424
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:101
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:230
bool isVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
The link is a partial right direction.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons) ...
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:99
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1266
LaneChangeMode myCooperativeLC
lane changing with the intent to help other vehicles
Definition: MSVehicle.h:1422
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:3156
int getRoutePosition() const
Definition: MSVehicle.cpp:707
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
bool containerTriggered
whether an arriving container lets the vehicle continue
void move2side(double amount)
move position vector to side using certain ammount
int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:3734
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:727
void stopEnded(const SUMOVehicle *veh, const MSVehicle::Stop &stop)
Definition: MSStopOut.cpp:94
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
Definition: MSVehicle.cpp:3714
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:93
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
double getJMParam(const SumoXMLAttr attr, const double defaultValue) const
Returns the named value from the map, or the default if it is not contained there.
double getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:3632
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:4382
SUMOVehicleShape getGuiShape() const
Get this vehicle type&#39;s shape.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
void planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector &lfLinks, double &myStopDist) const
Definition: MSVehicle.cpp:1557
double getWidth() const
Returns the edges&#39;s width (sum over all lanes)
Definition: MSEdge.h:548
std::string lane
The lane to stop at.
bool myEmergencyBrakeRedLight
Whether red lights are a reason to brake.
Definition: MSVehicle.h:1406
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:734
Influencer()
Constructor.
Definition: MSVehicle.cpp:239
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:962
std::vector< std::string > via
List of the via-edges the vehicle must visit.
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
ConstMSEdgeVector myVTDRoute
Definition: MSVehicle.h:1414
virtual void drawOutsideNetwork(bool)
register vehicle for drawing while outside the network
Definition: MSVehicle.h:1525
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
bool wasRemoteControlled(SUMOTime lookBack=DELTA_T) const
Returns the information whether the vehicle is fully controlled via TraCI within the lookBack time...
Definition: MSVehicle.cpp:4273
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:3485
std::pair< const MSPerson *, double > PersonDist
Definition: MSPModel.h:44
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:3789
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself ...
Definition: MSEdge.cpp:691
double getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.cpp:334
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2252
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
bool addTraciStop(MSLane *const lane, const double startPos, const double endPos, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, std::string &errorMsg)
Definition: MSVehicle.cpp:4043
double getLength() const
Get vehicle&#39;s length [m].
stop for vehicles
double departPos
(optional) The position the vehicle shall depart from
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1553
void registerOneWaitingForContainer()
increases the count of vehicles waiting for a container to allow recogniztion of container related de...
vehicle want&#39;s to change to left lane
Definition: MSVehicle.h:226
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:42
The vehicle starts or ends parking.
~Influencer()
Destructor.
Definition: MSVehicle.cpp:259
static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const std::map< int, double > *param=0)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
void addStops(const bool ignoreStopErrors)
Adds stops to the built vehicle.
double getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:204
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:4223
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:80
bool getEmergencyBrakeRedLight() const
Returns whether red lights shall be a reason to brake.
Definition: MSVehicle.h:1319
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:721
LaneChangeMode mySublaneLC
changing to the prefered lateral alignment
Definition: MSVehicle.h:1428
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1284
virtual VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting...
Definition: MSCFModel.h:195
void setNoShadowPartialOccupator(MSLane *lane)
void setTentativeLaneAndPosition(MSLane *lane, double pos, double posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:3808
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:844
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
#define M_PI
Definition: odrSpiral.cpp:40
void setVTDState(Position xyPos)
sets position outside the road network
Definition: MSVehicle.cpp:4260
std::vector< std::pair< SUMOTime, double > > mySpeedTimeLine
The velocity time line to apply.
Definition: MSVehicle.h:1379
SUMOTime getLastAccessTimeStep() const
Definition: MSVehicle.h:1347
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:200
MSVehicleType * myType
This vehicle&#39;s type.
void passTime(SUMOTime dt, bool waiting)
Definition: MSVehicle.cpp:201
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
Definition: MSCFModel.cpp:206
void workOnMoveReminders(double oldPos, double newPos, double newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:744
The vehicle is blocked being overlapping.
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1577
void resetChanged()
reset the flag whether a vehicle already moved to false
std::vector< MSLane * > bestContinuations
Definition: MSVehicle.h:733
std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:3574
Definition of vehicle stop (position and duration)
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:296
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:850
void onDepart()
Called when the vehicle is inserted into the network.
bool isStoppedInRange(double pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:1278
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:840
double estimateSpeedAfterDistance(const double dist, const double v, const double accel) const
Definition: MSCFModel.cpp:595
MSStoppingPlace * getContainerStop(const std::string &id) const
Returns the named container stop.
Definition: MSNet.cpp:888
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:1496
int index
at which position in the stops list
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:822
const waitingIntervalList & getWaitingIntervals() const
Definition: MSVehicle.h:201
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:591
void activateReminders(const MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
"Activates" all current move reminder
Definition: MSVehicle.cpp:2918
double implicitSpeedVTD(const MSVehicle *veh, double oldSpeed)
return the speed that is implicit in the new VTD position
Definition: MSVehicle.cpp:512
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
int myNumberReroutes
The number of reroutings.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:462
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2679
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to)
Informs all added listeners about a vehicle&#39;s state change.
Definition: MSNet.cpp:848
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:442
double getBeginLanePosition() const
Returns the begin position of this stop.
double getAccumulatedWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s) within the last millisecs...
Definition: MSVehicle.h:591
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:1272
static MSStopOut * getInstance()
Definition: MSStopOut.h:68
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:58
void checkLinkLeader(const MSLink *link, const MSLane *lane, double seen, DriveProcessItem *const lastLink, double &v, double &vLinkPass, double &vLinkWait, bool &setRequest, bool isShadowLink=false) const
checks for link leaders on the given link
Definition: MSVehicle.cpp:2014
waitingIntervalList myWaitingIntervals
Definition: MSVehicle.h:212
double getDistanceBetween(double fromPos, double 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:281
std::vector< DriveProcessItem > DriveItemVector
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1655
void setSignals(int signals)
Definition: MSVehicle.h:1363
double getEndPos(const SUMOVehicle &veh) const
return halting position for upcoming stop;
Definition: MSVehicle.cpp:4319
double pos() const
Position of this state.
Definition: MSVehicle.h:113
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
The action is due to a TraCI request.
#define DEBUG_COND
double getRightSideOnEdge() const
Definition: MSLane.h:935
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:916
vehicle want&#39;s to keep the current lane
Definition: MSVehicle.h:230
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
The vehicle needs another parking area.
const std::set< MSTransportable * > & getPersons() const
Returns this edge&#39;s persons set.
Definition: MSEdge.h:177
bool closeTag()
Closes the most recently opened tag.
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1139
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:63
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1131
double getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:3644
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:3662
double getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:3620
double getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3824
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1557
double estimateLeaveSpeed(const MSLink *const link, const double vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:1669
long long int SUMOTime
Definition: TraCIDefs.h:52
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:152
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
int getSpeedMode() const
return the current speed mode
Definition: MSVehicle.cpp:280
SUMOTime cumulatedWaitingTime(SUMOTime memory=-1) const
Definition: MSVehicle.cpp:180
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:270
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it&#39;s primary lane ...
Definition: MSVehicle.cpp:3912
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:604
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:424
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:1779
No information given; use default.
SUMOTime getDeparture() const
Returns this vehicle&#39;s real departure time.
MSParkingArea * getNextParkingArea()
get the current parking area stop
Definition: MSVehicle.cpp:1226
double getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:3656
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:105
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:521
double endPos
The stopping position end.
Definition: MSVehicle.h:836
State(double pos, double speed, double posLat, double backPos)
Constructor.
Definition: MSVehicle.cpp:152
bool mySpeedAdaptationStarted
Whether influencing the speed has already started.
Definition: MSVehicle.h:1391
SUMOEmissionClass getEmissionClass() const
Get this vehicle type&#39;s emission class.
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
Position validatePosition(Position result, double offset=0) const
ensure that a vehicle-relative position is not invalid
Definition: MSVehicle.cpp:900
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:499
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:727
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:4247
public emergency vehicles
render as a wagon passenger vehicle ("Combi")
void removeTransportable(MSTransportable *transportable)
Remove a passenger (TraCI)
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:89
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane&#39;s move reminders.
Definition: MSLane.h:229
int influenceChangeDecision(const SUMOTime currentTime, const MSEdge &currentEdge, const int currentLaneIndex, int state)
Applies stored LaneChangeMode information and laneTimeLine.
Definition: MSVehicle.cpp:340
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
void writeParams(OutputDevice &out) const
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:826
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&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:722
std::vector< MSDevice * > myDevices
The devices this vehicle has.
double myBackPos
the stored back position
Definition: MSVehicle.h:151
bool onFurtherEdge(const MSEdge *edge) const
whether this vehicle has its back (and no its front) on the given edge
Definition: MSVehicle.cpp:4031
void adaptLaneEntering2MoveReminder(const MSLane &enteredLane)
Adapts the vehicle&#39;s entering of a new lane.
Definition: MSVehicle.cpp:773
Back-at-zero position.
LaneChangeMode myStrategicLC
lane changing which is necessary to follow the current route
Definition: MSVehicle.h:1420
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:472
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time tau (i...
Definition: MSCFModel.h:290
bool isFringe() const
return whether this edge is at the fringe of the network
Definition: MSEdge.h:646
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:237
Interface for lane-change models.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
double mySpeed
the stored speed (should be >=0 at any time)
Definition: MSVehicle.h:143
int getBestLaneOffset() const
Definition: MSVehicle.cpp:3531
bool myConsiderSafeVelocity
Whether the safe velocity shall be regarded.
Definition: MSVehicle.h:1394
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Definition: Position.h:260
SUMOTime myDeparture
The real departure time.
void removeTransportable(MSTransportable *t)
removes a person or container
Definition: MSVehicle.cpp:3704
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
MSDevice_Transportable * myContainerDevice
The containers this vehicle may have.
Definition: MSVehicle.h:1567
static const SUMOTime NOT_YET_DEPARTED
double getMinimalArrivalSpeedEuler(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance for Euler update...
Definition: MSCFModel.cpp:381
double startPos
The stopping position start.
Definition: MSVehicle.h:834
std::string id
The vehicle&#39;s id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:846
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:278
The vehicle is being teleported.
double getWidth() const
Returns the vehicle&#39;s width.
const std::string & getID() const
Returns the name of the vehicle.
int size() const
Return the number of passengers / containers.
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:443
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
const Position getBackPosition() const
Definition: MSVehicle.cpp:976
bool ignoreRed(const MSLink *link, bool canBrake) const
decide whether a red (or yellow light) may be ignore
Definition: MSVehicle.cpp:4346