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