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