SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-sim.org/
20 // Copyright (C) 2001-2013 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>
47 #include <utils/common/ToString.h>
54 #include <utils/common/StdDefs.h>
55 #include <utils/geom/Line.h>
60 #include <microsim/MSGlobals.h>
61 #include "trigger/MSBusStop.h"
63 #include "MSEdgeWeightsStorage.h"
65 #include "MSMoveReminder.h"
66 #include "MSPerson.h"
67 #include "MSPersonControl.h"
68 #include "MSLane.h"
69 #include "MSVehicle.h"
70 #include "MSEdge.h"
71 #include "MSVehicleType.h"
72 #include "MSNet.h"
73 #include "MSRoute.h"
74 #include "MSLinkCont.h"
75 
76 #ifdef HAVE_INTERNAL
77 #include <mesosim/MESegment.h>
78 #include <mesosim/MELoop.h>
79 #include "MSGlobals.h"
80 #endif
81 
82 #ifdef CHECK_MEMORY_LEAKS
83 #include <foreign/nvwa/debug_new.h>
84 #endif // CHECK_MEMORY_LEAKS
85 
86 //#define DEBUG_VEHICLE_GUI_SELECTION 1
87 #ifdef DEBUG_VEHICLE_GUI_SELECTION
88 #undef ID_LIST
90 #include <guisim/GUIVehicle.h>
91 #include <guisim/GUILane.h>
92 #endif
93 
94 #define BUS_STOP_OFFSET 0.5
95 
96 #define CRLL_LOOK_AHEAD 5
97 
98 
99 // ===========================================================================
100 // static value definitions
101 // ===========================================================================
102 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
103 
104 
105 // ===========================================================================
106 // method definitions
107 // ===========================================================================
108 /* -------------------------------------------------------------------------
109  * methods of MSVehicle::State
110  * ----------------------------------------------------------------------- */
112  myPos = state.myPos;
113  mySpeed = state.mySpeed;
114 }
115 
116 
119  myPos = state.myPos;
120  mySpeed = state.mySpeed;
121  return *this;
122 }
123 
124 
125 bool
127  return (myPos != state.myPos ||
128  mySpeed != state.mySpeed);
129 }
130 
131 
132 SUMOReal
134  return myPos;
135 }
136 
137 
139  myPos(pos), mySpeed(speed) {}
140 
141 
142 /* -------------------------------------------------------------------------
143  * methods of MSVehicle::Influencer
144  * ----------------------------------------------------------------------- */
145 #ifndef NO_TRACI
147  mySpeedAdaptationStarted(true),
148  myConsiderSafeVelocity(true),
149  myConsiderMaxAcceleration(true),
150  myConsiderMaxDeceleration(true),
151  myAmVTDControlled(false),
152  myStrategicLC(LC_NOCONFLICT),
153  myCooperativeLC(LC_NOCONFLICT),
154  mySpeedGainLC(LC_NOCONFLICT),
155  myRightDriveLC(LC_NOCONFLICT),
156  myTraciLaneChangePriority(LCP_URGENT)
157 {}
158 
159 
161 
162 
163 void
164 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
165  mySpeedAdaptationStarted = true;
166  mySpeedTimeLine = speedTimeLine;
167 }
168 
169 
170 void
171 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, unsigned int> >& laneTimeLine) {
172  myLaneTimeLine = laneTimeLine;
173 }
174 
175 
176 SUMOReal
178  // keep original speed
179  myOriginalSpeed = speed;
180  // remove leading commands which are no longer valid
181  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
182  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
183  }
184  // do nothing if the time line does not apply for the current time
185  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
186  return speed;
187  }
188  // compute and set new speed
189  if (!mySpeedAdaptationStarted) {
190  mySpeedTimeLine[0].second = speed;
191  mySpeedAdaptationStarted = true;
192  }
193  currentTime += DELTA_T;
194  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
195  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
196  if (myConsiderSafeVelocity) {
197  speed = MIN2(speed, vSafe);
198  }
199  if (myConsiderMaxAcceleration) {
200  speed = MIN2(speed, vMax);
201  }
202  if (myConsiderMaxDeceleration) {
203  speed = MAX2(speed, vMin);
204  }
205  return speed;
206 }
207 
208 
209 int
210 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const unsigned int currentLaneIndex, int state) {
211  // remove leading commands which are no longer valid
212  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
213  myLaneTimeLine.erase(myLaneTimeLine.begin());
214  }
215  ChangeRequest changeRequest = REQUEST_NONE;
216  // do nothing if the time line does not apply for the current time
217  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
218  const unsigned int destinationLaneIndex = myLaneTimeLine[1].second;
219  if (destinationLaneIndex < (unsigned int)currentEdge.getLanes().size()) {
220  if (currentLaneIndex > destinationLaneIndex) {
221  changeRequest = REQUEST_RIGHT;
222  } else if (currentLaneIndex < destinationLaneIndex) {
223  changeRequest = REQUEST_LEFT;
224  } else {
225  changeRequest = REQUEST_HOLD;
226  }
227  }
228  }
229  // check whether the current reason shall be canceled / overridden
230  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
231  // flags for the current reason
232  LaneChangeMode mode = LC_NEVER;
233  if ((state & LCA_STRATEGIC) != 0) {
234  mode = myStrategicLC;
235  } else if ((state & LCA_COOPERATIVE) != 0) {
236  mode = myCooperativeLC;
237  } else if ((state & LCA_SPEEDGAIN) != 0) {
238  mode = mySpeedGainLC;
239  } else if ((state & LCA_KEEPRIGHT) != 0) {
240  mode = myRightDriveLC;
241  } else if ((state & LCA_TRACI) != 0) {
242  mode = LC_NEVER;
243  } else {
244  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
245  }
246  if (mode == LC_NEVER) {
247  // cancel all lcModel requests
248  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
249  state &= ~LCA_URGENT;
250  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
251  if (
252  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
253  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
254  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
255  // cancel conflicting lcModel request
256  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
257  state &= ~LCA_URGENT;
258  }
259  } else if (mode == LC_ALWAYS) {
260  // ignore any TraCI requests
261  return state;
262  }
263  }
264  // apply traci requests
265  if (changeRequest == REQUEST_NONE) {
266  return state;
267  } else {
268  state |= LCA_TRACI;
269  // security checks
270  if ((myTraciLaneChangePriority == LCP_ALWAYS)
271  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
272  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
273  }
274  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
275  state |= LCA_URGENT;
276  }
277  switch (changeRequest) {
278  case REQUEST_HOLD:
279  return state | LCA_STAY;
280  case REQUEST_LEFT:
281  return state | LCA_LEFT;
282  case REQUEST_RIGHT:
283  return state | LCA_RIGHT;
284  default:
285  throw ProcessError("should not happen");
286  }
287  }
288 }
289 
290 
291 SUMOReal
293  assert(myLaneTimeLine.size() >= 2);
294  assert(currentTime >= myLaneTimeLine[0].first);
295  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
296 }
297 
298 
299 void
301  myConsiderSafeVelocity = value;
302 }
303 
304 
305 void
307  myConsiderMaxAcceleration = value;
308 }
309 
310 
311 void
313  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
314  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
315  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
316  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
317  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
318 }
319 
320 
321 void
323  myConsiderMaxDeceleration = value;
324 }
325 
326 
327 void
331  if (myVTDRoute.size() != 0) {
332  v->replaceRouteEdges(myVTDRoute, true);
333  }
334  v->myCurrEdge += myVTDEdgeOffset;
335  if (myVTDPos > myVTDLane->getLength()) {
336  myVTDPos = myVTDLane->getLength();
337  }
338  myVTDLane->forceVehicleInsertion(v, myVTDPos);
339  v->getBestLanes();
340  myAmVTDControlled = false;
341 }
342 
343 #endif
344 
345 
346 /* -------------------------------------------------------------------------
347  * MSVehicle-methods
348  * ----------------------------------------------------------------------- */
350  delete myLaneChangeModel;
351  // other
352  delete myEdgeWeights;
353  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
354  (*i)->resetPartialOccupation(this);
355  }
356  myFurtherLanes.clear();
357  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
358  if ((*i).myLink != 0) {
359  (*i).myLink->removeApproaching(this);
360  }
361  }
362  //
363  if (myType->amVehicleSpecific()) {
364  delete myType;
365  }
366 #ifndef NO_TRACI
367  delete myInfluencer;
368 #endif
369 }
370 
371 
373  const MSRoute* route,
374  const MSVehicleType* type,
375  SUMOReal speedFactor) :
376  MSBaseVehicle(pars, route, type, speedFactor),
377  myWaitingTime(0),
378  myState(0, 0), //
379  myLane(0),
382  myPersonDevice(0),
383  myAcceleration(0),
384  mySignals(0),
385  myAmOnNet(false),
387  myHaveToWaitOnNextLink(false),
388  myCachedPosition(Position::INVALID),
389  myEdgeWeights(0)
390 #ifndef NO_TRACI
391  , myInfluencer(0)
392 #endif
393 {
394  for (std::vector<SUMOVehicleParameter::Stop>::iterator i = pars->stops.begin(); i != pars->stops.end(); ++i) {
395  if (!addStop(*i)) {
396  throw ProcessError("Stop for vehicle '" + pars->id +
397  "' on lane '" + i->lane + "' is not downstream the current route.");
398  }
399  }
400  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = route->getStops().begin(); i != route->getStops().end(); ++i) {
401  if (!addStop(*i)) {
402  throw ProcessError("Stop for vehicle '" + pars->id +
403  "' on lane '" + i->lane + "' is not downstream the current route.");
404  }
405  }
406  const MSLane* const depLane = (*myCurrEdge)->getDepartLane(*this);
407  if (depLane == 0) {
408  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
409  }
410  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > depLane->getVehicleMaxSpeed(this)) {
411  if (type->getSpeedDeviation() > 0 && pars->departSpeed <= type->getSpeedFactor() * depLane->getSpeedLimit() * (2 * type->getSpeedDeviation() + 1.)) {
412  WRITE_WARNING("Choosing new speed factor for vehicle '" + pars->id + "' to match departure speed.");
414  } else {
415  throw ProcessError("Departure speed for vehicle '" + pars->id +
416  "' is too high for the departure lane '" + depLane->getID() + "'.");
417  }
418  }
419  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
420  throw ProcessError("Departure speed for vehicle '" + pars->id +
421  "' is too high for the vehicle type '" + type->getID() + "'.");
422  }
425 }
426 
427 
428 void
431  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
432  if ((*i).myLink != 0) {
433  (*i).myLink->removeApproaching(this);
434  }
435  }
436  leaveLane(reason);
437 }
438 
439 
440 // ------------ interaction with the route
441 bool
443  return myCurrEdge == myRoute->end() - 1 && myState.myPos > myArrivalPos - POSITION_EPS;
444 }
445 
446 
447 bool
448 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit) {
449  const MSEdgeVector& edges = newRoute->getEdges();
450  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
451  if (!onInit && !newRoute->contains(*myCurrEdge)) {
452  return false;
453  }
454 
455  // rebuild in-vehicle route information
456  if (onInit) {
457  myCurrEdge = newRoute->begin();
458  } else {
459  myCurrEdge = find(edges.begin(), edges.end(), *myCurrEdge);
460  }
461  // check whether the old route may be deleted (is not used by anyone else)
462  newRoute->addReference();
463  myRoute->release();
464  // assign new route
465  myRoute = newRoute;
468  if (!onInit) {
469  getBestLanes(true);
470  }
471  // update arrival definition
473  // save information that the vehicle was rerouted
476  // recheck stops
477  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
478  if (find(edges.begin(), edges.end(), &iter->lane->getEdge()) == edges.end()) {
479  iter = myStops.erase(iter);
480  } else {
481  iter->edge = find(edges.begin(), edges.end(), &iter->lane->getEdge());
482  ++iter;
483  }
484  }
485  return true;
486 }
487 
488 
489 bool
490 MSVehicle::willPass(const MSEdge* const edge) const {
491  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
492 }
493 
494 
495 unsigned int
497  return (unsigned int) std::distance(myRoute->begin(), myCurrEdge);
498 }
499 
500 
501 void
502 MSVehicle::resetRoutePosition(unsigned int index) {
503  myCurrEdge = myRoute->begin() + index;
504  // !!! hack
505  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
506 }
507 
508 
509 
512  return _getWeightsStorage();
513 }
514 
515 
518  return _getWeightsStorage();
519 }
520 
521 
524  if (myEdgeWeights == 0) {
526  }
527  return *myEdgeWeights;
528 }
529 
530 
531 // ------------ Interaction with move reminders
532 void
534  // This erasure-idiom works for all stl-sequence-containers
535  // See Meyers: Effective STL, Item 9
536  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
537  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
538 #ifdef _DEBUG
539  if (myTraceMoveReminders) {
540  traceMoveReminder("notifyMove", rem->first, rem->second, false);
541  }
542 #endif
543  rem = myMoveReminders.erase(rem);
544  } else {
545 #ifdef _DEBUG
546  if (myTraceMoveReminders) {
547  traceMoveReminder("notifyMove", rem->first, rem->second, true);
548  }
549 #endif
550  ++rem;
551  }
552  }
553 }
554 
555 
556 void
558  // save the old work reminders, patching the position information
559  // add the information about the new offset to the old lane reminders
560  const SUMOReal oldLaneLength = myLane->getLength();
561  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
562  rem->second += oldLaneLength;
563 #ifdef _DEBUG
564  if (myTraceMoveReminders) {
565  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
566  }
567 #endif
568  }
569  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
570  addReminder(*rem);
571  }
572 }
573 
574 
575 // ------------ Other getter methods
576 Position
577 MSVehicle::getPosition(const SUMOReal offset) const {
578  if (myLane == 0) {
579  return Position::INVALID;
580  }
581  if (isParking()) {
582  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
585  }
586  const bool changingLanes = getLaneChangeModel().isChangingLanes();
587  if (offset == 0. && !changingLanes) {
590  }
591  return myCachedPosition;
592  }
594  if (changingLanes) {
596  Line line = getLaneChangeModel().isLaneChangeMidpointPassed() ? Line(other, result) : Line(result, other);
597  return line.getPositionAtDistance(getLaneChangeModel().getLaneChangeCompletion() * line.length());
598  }
599  return result;
600 }
601 
602 
603 SUMOReal
606  Position p2 = myFurtherLanes.size() > 0
607  ? myFurtherLanes.back()->getShape().positionAtOffset(myFurtherLanes.back()->getPartialOccupatorEnd())
609  SUMOReal result = (p1 != p2 ?
610  atan2(p1.x() - p2.x(), p2.y() - p1.y()) * 180. / PI :
614  result += getLaneChangeModel().getLaneChangeDirection() * angleOffset;
615  }
616  return result;
617 }
618 
619 
620 // ------------
621 bool
623  Stop stop;
624  stop.lane = MSLane::dictionary(stopPar.lane);
625  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
626  stop.startPos = stopPar.startPos;
627  stop.endPos = stopPar.endPos;
628  stop.duration = stopPar.duration;
629  stop.until = stopPar.until;
630  stop.awaitedPersons = stopPar.awaitedPersons;
631  if (stop.until != -1) {
632  stop.until += untilOffset;
633  }
634  stop.triggered = stopPar.triggered;
635  stop.parking = stopPar.parking;
636  stop.reached = false;
637  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
638  return false;
639  }
640  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
641  MSRouteIterator prevStopEdge = myCurrEdge;
642  SUMOReal prevStopPos = myState.myPos;
643  // where to insert the stop
644  std::list<Stop>::iterator iter = myStops.begin();
645  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
646  if (myStops.size() > 0) {
647  prevStopEdge = myStops.back().edge;
648  prevStopPos = myStops.back().endPos;
649  iter = myStops.end();
650  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
651  }
652  } else {
653  if (stopPar.index == STOP_INDEX_FIT) {
654  while (iter != myStops.end() && (iter->edge < stop.edge ||
655  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
656  prevStopEdge = iter->edge;
657  prevStopPos = iter->endPos;
658  ++iter;
659  }
660  } else {
661  int index = stopPar.index;
662  while (index > 0) {
663  prevStopEdge = iter->edge;
664  prevStopPos = iter->endPos;
665  ++iter;
666  --index;
667  }
668  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
669  }
670  }
671  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
672  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
673  return false;
674  }
675  // David.C:
676  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
678  return false;
679  }
680  if (!hasDeparted() && myCurrEdge == stop.edge) {
681  SUMOReal pos = -1;
683  pos = myParameter->departPos;
684  if (pos < 0.) {
685  pos += (*myCurrEdge)->getLength();
686  }
687  }
689  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
690  }
691  if (pos > stop.endPos) {
692  return false;
693  }
694  }
695  myStops.insert(iter, stop);
696  return true;
697 }
698 
699 
700 bool
702  return !myStops.empty() && myStops.begin()->reached;
703 }
704 
705 
706 bool
708  return isStopped() && myStops.begin()->parking;
709 }
710 
711 
712 bool
714  return isStopped() && myStops.begin()->triggered;
715 }
716 
717 
718 SUMOReal
720  if (myStops.empty()) {
721  // no stops; pass
722  return currentVelocity;
723  }
724  Stop& stop = myStops.front();
725  if (stop.reached) {
726  // ok, we have already reached the next stop
727  // any waiting persons may board now
728  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this);
729  boarded &= stop.awaitedPersons.size() == 0;
730  if (boarded) {
731  if (stop.busstop != 0) {
732  const std::vector<MSPerson*>& persons = myPersonDevice->getPersons();
733  for (std::vector<MSPerson*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
734  stop.busstop->removePerson(*i);
735  }
736  }
737  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
738  stop.triggered = false;
742  }
743  }
744  if (stop.duration <= 0 && !stop.triggered) {
745  // we have waited long enough and fulfilled any passenger-requirements
746  if (stop.busstop != 0) {
747  // inform bus stop about leaving it
748  stop.busstop->leaveFrom(this);
749  }
750  // the current stop is no longer valid
752  myStops.pop_front();
753  // do not count the stopping time towards gridlock time.
754  // Other outputs use an independent counter and are not affected.
755  myWaitingTime = 0;
756  // maybe the next stop is on the same edge; let's rebuild best lanes
757  getBestLanes(true);
758  // continue as wished...
760  } else {
761  // we have to wait some more time
763  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
766  }
767  stop.duration -= DELTA_T;
768  return 0;
769  }
770  } else {
771  // is the next stop on the current lane?
772  if (stop.edge == myCurrEdge) {
773  // get the stopping position
774  SUMOReal endPos = stop.endPos;
775  bool busStopsMustHaveSpace = true;
776  if (stop.busstop != 0) {
777  // on bus stops, we have to wait for free place if they are in use...
778  endPos = stop.busstop->getLastFreePos(*this);
779  if (endPos - 5. < stop.busstop->getBeginLanePosition()) { // !!! explicit offset
780  busStopsMustHaveSpace = false;
781  }
782  }
783  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace) {
784  // ok, we may stop (have reached the stop)
785  stop.reached = true;
788  // compute stopping time
789  if (stop.until >= 0) {
790  if (stop.duration == -1) {
792  } else {
794  }
795  }
796  if (stop.busstop != 0) {
797  // let the bus stop know the vehicle
799  }
800  }
801  // decelerate
802  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos());
803  }
804  }
805  return currentVelocity;
806 }
807 
808 
809 void
810 MSVehicle::planMove(const SUMOTime t, const MSVehicle* pred, const SUMOReal lengthsInFront) {
812  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
814 }
815 
816 
817 void
818 MSVehicle::planMoveInternal(const SUMOTime t, const MSVehicle* pred, DriveItemVector& lfLinks) const {
819 #ifdef DEBUG_VEHICLE_GUI_SELECTION
820  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
821  int bla = 0;
822  }
823 #endif
824  // remove information about approaching links, will be reset later in this step
825  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
826  if ((*i).myLink != 0) {
827  (*i).myLink->removeApproaching(this);
828  }
829  }
830  lfLinks.clear();
831 #ifdef HAVE_INTERNAL_LANES
832  myLinkLeaders.clear();
833 #endif
834  //
835  const MSCFModel& cfModel = getCarFollowModel();
836  const SUMOReal vehicleLength = getVehicleType().getLength();
837  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
838  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
839  // vBeg is the initial maximum velocity of this vehicle in this step
840  SUMOReal v = MIN2(maxV, laneMaxV);
841 #ifndef NO_TRACI
842  if (myInfluencer != 0) {
843  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
844  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
845  // !!! recheck - why is it done, here?
846  if (myInfluencer->isVTDControlled()) {
847  return; // !!! temporary
848  }
849  }
850 #endif
851 
852  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
853  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
854  assert(bestLaneConts.size() > 0);
855 #ifdef HAVE_INTERNAL_LANES
856  bool hadNonInternal = false;
857 #else
858  bool hadNonInternal = true;
859 #endif
860  SUMOReal seen = myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
861  SUMOReal seenNonInternal = 0;
862  SUMOReal vLinkPass = MIN2(estimateSpeedAfterDistance(seen, v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
863  unsigned int view = 0;
864  DriveProcessItem* lastLink = 0;
865  SUMOReal gap = 0;
866  if (pred != 0) {
867  if (pred == myLane->getPartialOccupator()) {
869  } else {
871  }
872  }
873  std::pair<const MSVehicle*, SUMOReal> leaderInfo = std::make_pair(pred, gap);
874  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
875  const MSLane* lane = myLane;
876  while (true) {
877  // check leader on lane
878  // leader is given for the first edge only
879  adaptToLeader(leaderInfo, seen, lastLink, lane, v, vLinkPass);
880 
881  // process stops
882  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
883  // we are approaching a stop on the edge; must not drive further
884  const Stop& stop = *myStops.begin();
885  SUMOReal stopDist = stop.busstop == 0 ? seen + stop.endPos - lane->getLength() : seen + stop.busstop->getLastFreePos(*this) - POSITION_EPS - lane->getLength();
886  SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), stopDist);
887  if (lastLink != 0) {
888  lastLink->adaptLeaveSpeed(stopSpeed);
889  }
890  v = MIN2(v, stopSpeed);
891  lfLinks.push_back(DriveProcessItem(v, stopDist));
892  break;
893  }
894 
895  // move to next lane
896  // get the next link used
897  MSLinkCont::const_iterator link = myLane->succLinkSec(*this, view + 1, *lane, bestLaneConts);
898  // check whether the vehicle is on its final edge
899  if (myCurrEdge + view + 1 == myRoute->end()) {
901  myParameter->arrivalSpeed : laneMaxV);
902  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
903  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
904  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
905  v = MIN2(v, va);
906  if (lastLink != 0) {
907  lastLink->adaptLeaveSpeed(va);
908  }
909  lfLinks.push_back(DriveProcessItem(v, seen));
910  break;
911  }
912  // check whether the lane is a dead end
913  // @todo: recheck propper value for laneStopOffset based on real-world
914  // measurements.
915  // For links that require stopping it is important that vehicles stop close to the stopping line
916  const SUMOReal laneStopOffset = ((lane->getLength() <= getVehicleType().getMinGap()
917  || (!lane->isLinkEnd(link) && (
918  (*link)->getState() == LINKSTATE_ALLWAY_STOP || (*link)->getState() == LINKSTATE_STOP)))
920  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
921  if (lane->isLinkEnd(link)) {
922  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), stopDist), laneMaxV);
923  if (lastLink != 0) {
924  lastLink->adaptLeaveSpeed(va);
925  }
926  v = MIN2(va, v);
927  lfLinks.push_back(DriveProcessItem(v, seen));
928  break;
929  }
930  // check whether we need to slow down in order to finish a continuous lane change
931  if (getLaneChangeModel().isChangingLanes()) {
932  if ( // slow down to finish lane change before a turn lane
933  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
934  // slow down to finish lane change before the shadow lane ends
936  (*link)->getViaLaneOrLane()->getParallelLane(-getLaneChangeModel().getLaneChangeDirection()) == 0)) {
937  const SUMOReal timeRemaining = STEPS2TIME((1 - getLaneChangeModel().getLaneChangeCompletion()) * MSGlobals::gLaneChangeDuration);
938  const SUMOReal va = seen / timeRemaining;
939  v = MIN2(va, v);
940  }
941  }
942 
943  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
944  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
945  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
946  const bool setRequest = v > 0; // even if red, if we cannot break we should issue a request
947  const SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
948  if (yellowOrRed && seen > cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime()) {
949  // the vehicle is able to brake in front of a yellow/red traffic light
950  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / vLinkWait), vLinkWait, 0, SUMOTime_MAX, stopDist));
951  // XXX division by 0 (vLinkWait) should be avoided
952  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
953  break;
954  }
955 
956 #ifdef HAVE_INTERNAL_LANES
957  // we want to pass the link but need to check for foes on internal lanes
958  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
959  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
960  // the vehicle to enter the junction first has priority
961  const MSVehicle* leader = it->first;
962  if (leader->myLinkLeaders.count(getID()) == 0) {
963  // leader isn't already following us, now we follow it
964  myLinkLeaders.insert(leader->getID());
965  adaptToLeader(*it, seen, lastLink, lane, v, vLinkPass);
966  if (lastLink != 0) {
967  // we are not yet on the junction with this linkLeader.
968  // at least we can drive up to the previous link and stop there
969  v = MAX2(v, lastLink->myVLinkWait);
970  }
971  }
972  }
973 #endif
974 
975  if (lastLink != 0) {
976  lastLink->adaptLeaveSpeed(laneMaxV);
977  }
978  SUMOReal arrivalSpeed = vLinkPass;
979  SUMOTime arrivalTime;
980  // vehicles should decelerate when approaching a minor link
981  if (!(*link)->havePriority() && stopDist > cfModel.getMaxDecel()) {
982  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
983  arrivalSpeed = cfModel.getMaxDecel() + cfModel.getMaxAccel();
984  const SUMOReal v1 = MAX2(vLinkWait, arrivalSpeed);
985  // now + time spent decelerating + time spent at full speed
986  arrivalTime = t + TIME2STEPS((v1 - arrivalSpeed) / cfModel.getMaxDecel()
987  + (seen - (v1 * v1 - arrivalSpeed * arrivalSpeed) * 0.5 / cfModel.getMaxDecel()) / vLinkWait);
988  } else {
989  const SUMOReal accel = (vLinkPass >= v) ? cfModel.getMaxAccel() : -cfModel.getMaxDecel();
990  const SUMOReal accelTime = (vLinkPass - v) / accel;
991  const SUMOReal accelWay = accelTime * (vLinkPass + v) * 0.5;
992  arrivalTime = t + TIME2STEPS(accelTime + MAX2(SUMOReal(0), seen - accelWay) / vLinkPass);
993  }
994  // compute speed, time if vehicle starts braking now
995  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
996  SUMOReal arrivalSpeedBraking = 0;
997  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
998  if (seen < cfModel.brakeGap(v)) {
999  // vehicle cannot come to a complete stop in time
1000  // Because we use a continuous formula for computiing the possible slow-down
1001  // we need to handle the mismatch with the discrete dynamics
1002  if (seen < v) {
1003  arrivalSpeedBraking = arrivalSpeed; // no time left for braking after this step
1004  } else if (2 * seen * -getVehicleType().getCarFollowModel().getMaxDecel() + v * v >= 0) {
1005  arrivalSpeedBraking = estimateSpeedAfterDistance(seen, v, -getVehicleType().getCarFollowModel().getMaxDecel());
1006  }
1007  // due to discrecte/continuous mismatch we have to ensure that braking actually helps
1008  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1009  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1010  }
1011  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1012  arrivalTime, arrivalSpeed,
1013  arrivalTimeBraking, arrivalSpeedBraking,
1014  stopDist,
1015  estimateLeaveSpeed(*link, vLinkPass)));
1016 #ifdef HAVE_INTERNAL_LANES
1017  if ((*link)->getViaLane() == 0) {
1018  hadNonInternal = true;
1019  ++view;
1020  }
1021 #else
1022  ++view;
1023 #endif
1024  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1025  if (!setRequest || ((v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD)) {
1026  break;
1027  }
1028  // get the following lane
1029  lane = (*link)->getViaLaneOrLane();
1030  laneMaxV = lane->getVehicleMaxSpeed(this);
1031  // the link was passed
1032  // compute the velocity to use when the link is not blocked by other vehicles
1033  // the vehicle shall be not faster when reaching the next lane than allowed
1034  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1035  v = MIN2(va, v);
1036  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1037  seen += lane->getLength();
1038  leaderInfo = lane->getLastVehicleInformation();
1039  leaderInfo.second = leaderInfo.second + seen - lane->getLength() - getVehicleType().getMinGap();
1040  vLinkPass = MIN2(estimateSpeedAfterDistance(lane->getLength(), v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1041  lastLink = &lfLinks.back();
1042  }
1043 
1044 }
1045 
1046 
1047 void
1048 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1049  const SUMOReal seen, DriveProcessItem* const lastLink,
1050  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass) const {
1051  if (leaderInfo.first != 0) {
1052  const MSCFModel& cfModel = getCarFollowModel();
1053  SUMOReal vsafeLeader = 0;
1054  if (leaderInfo.second >= 0) {
1055  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1056  } else {
1057  // the leading, in-lapping vehicle is occupying the complete next lane
1058  // stop before entering this lane
1059  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1060  }
1061  if (lastLink != 0) {
1062  lastLink->adaptLeaveSpeed(vsafeLeader);
1063  }
1064  v = MIN2(v, vsafeLeader);
1065  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1066  }
1067 }
1068 
1069 
1070 bool
1072 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1073  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1074  int bla = 0;
1075  }
1076 #endif
1077  // get safe velocities from DriveProcessItems
1078  SUMOReal vSafe = 0; // maximum safe velocity
1079  SUMOReal vSafeMin = 0; // minimum safe velocity
1080  // the distance to a link which should either be crossed this step or in
1081  // front of which we need to stop
1082  SUMOReal vSafeMinDist = 0;
1083  myHaveToWaitOnNextLink = false;
1084 #ifndef NO_TRACI
1085  if (myInfluencer != 0) {
1086  if (myInfluencer->isVTDControlled()) {
1087  return false;
1088  }
1089  }
1090 #endif
1091 
1092  assert(myLFLinkLanes.size() != 0 || (myInfluencer != 0 && myInfluencer->isVTDControlled()));
1093  DriveItemVector::iterator i;
1094  bool braking = false;
1095  bool lastWasGreenCont = false;
1096  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1097  MSLink* link = (*i).myLink;
1098  // the vehicle must change the lane on one of the next lanes
1099  if (link != 0 && (*i).mySetRequest) {
1100  const LinkState ls = link->getState();
1101  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1102  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1104  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1105  vSafe = (*i).myVLinkWait;
1106  braking = true;
1107  lastWasGreenCont = false;
1108  link->removeApproaching(this);
1109  break;
1110  }
1111  //
1112  const bool opened = yellow || link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1114  // vehicles should decelerate when approaching a minor link
1115  if (opened && !lastWasGreenCont && !link->havePriority()) {
1116  if ((*i).myDistance > getCarFollowModel().getMaxDecel()) {
1117  vSafe = (*i).myVLinkWait;
1118  braking = true;
1119  lastWasGreenCont = false;
1120  if (ls == LINKSTATE_EQUAL) {
1121  link->removeApproaching(this);
1122  }
1123  break; // could be revalidated
1124  } else {
1125  // past the point of no return. we need to drive fast enough
1126  // to make it accross the link. However, minor slowdowns
1127  // should be permissible to follow leading traffic safely
1128  // There is a problem in subsecond simulation: If we cannot
1129  // make it across the minor link in one step, new traffic
1130  // could appear on a major foe link and cause a collision
1131  vSafeMin = MIN2((SUMOReal) DIST2SPEED(myLane->getLength() - getPositionOnLane() + POSITION_EPS), (*i).myVLinkPass);
1132  vSafeMinDist = myLane->getLength() - getPositionOnLane();
1133  }
1134  }
1135  // have waited; may pass if opened...
1136  if (opened) {
1137  vSafe = (*i).myVLinkPass;
1138  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1139  // this vehicle is probably not gonna drive accross the next junction (heuristic)
1140  myHaveToWaitOnNextLink = true;
1141  }
1142  lastWasGreenCont = link->isCont() && (ls == LINKSTATE_TL_GREEN_MAJOR);
1143  } else {
1144  lastWasGreenCont = false;
1145  vSafe = (*i).myVLinkWait;
1146  braking = true;
1147  if (ls == LINKSTATE_EQUAL) {
1148  link->removeApproaching(this);
1149  }
1150  break;
1151  }
1152  } else {
1153  vSafe = (*i).myVLinkWait;
1154  braking = vSafe < getSpeed();
1155  break;
1156  }
1157  }
1158  if (vSafe + NUMERICAL_EPS < vSafeMin) {
1159  // cannot drive across a link so we need to stop before it
1160  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1161  vSafeMin = 0;
1162  braking = true;
1163  }
1164  if (braking) {
1165  myHaveToWaitOnNextLink = true;
1166  }
1167 
1168  // apply speed reduction due to dawdling / lane changing but ensure minimum save speed
1169  SUMOReal vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1170  //if (vNext > vSafe) {
1171  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1172  // + toString(vSafe) + ", moving at " + toString(vNext) + " instead. time="
1173  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1174  //}
1175  vNext = MAX2(vNext, (SUMOReal) 0.);
1176 #ifndef NO_TRACI
1177  if (myInfluencer != 0) {
1179  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1180  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1181  if (myInfluencer->isVTDControlled()) {
1182  vNext = 0;
1183  }
1184  }
1185 #endif
1186  // visit waiting time
1187  if (vNext <= SUMO_const_haltingSpeed) {
1189  braking = true;
1190  } else {
1191  myWaitingTime = 0;
1192  }
1193  if (myState.mySpeed < vNext) {
1194  braking = false;
1195  }
1196  if (braking) {
1198  } else {
1200  }
1201  // call reminders after vNext is set
1202  const SUMOReal pos = myState.myPos;
1203 
1204  // update position and speed
1206  myState.myPos += SPEED2DIST(vNext);
1207  myState.mySpeed = vNext;
1209  std::vector<MSLane*> passedLanes;
1210  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1211  passedLanes.push_back(*i);
1212  }
1213  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1214  passedLanes.push_back(myLane);
1215  }
1216  bool moved = false;
1217  // move on lane(s)
1218  if (myState.myPos <= myLane->getLength()) {
1219  // we are staying at our lane
1220  // there is no need to go over succeeding lanes
1221  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
1222  } else {
1223  // we are moving at least to the next lane (maybe pass even more than one)
1224  if (myCurrEdge != myRoute->end() - 1) {
1225  MSLane* approachedLane = myLane;
1226  // move the vehicle forward
1227  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1229  MSLink* link = (*i).myLink;
1230  // check whether the vehicle was allowed to enter lane
1231  // otherwise it is decelareted and we do not need to test for it's
1232  // approach on the following lanes when a lane changing is performed
1233  // proceed to the next lane
1234  if (link != 0) {
1235  approachedLane = link->getViaLaneOrLane();
1236  } else {
1237  approachedLane = 0;
1238  }
1239  if (approachedLane != myLane && approachedLane != 0) {
1240  myState.myPos -= myLane->getLength();
1241  assert(myState.myPos > 0);
1242  enterLaneAtMove(approachedLane);
1243  myLane = approachedLane;
1244  if (getLaneChangeModel().isChangingLanes()) {
1245  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
1246  // abort lane change
1247  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
1248  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1250  }
1251  }
1252  moved = true;
1253  if (approachedLane->getEdge().isVaporizing()) {
1255  break;
1256  }
1257  }
1258  passedLanes.push_back(approachedLane);
1259  }
1260  }
1261  }
1262  // clear previously set information
1263  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1264  (*i)->resetPartialOccupation(this);
1265  }
1266  myFurtherLanes.clear();
1267 
1268  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
1269  myWaitingTime = 0;
1270 // myInfluencer->setVTDControlled(false);
1271  return false;
1272  }
1273 
1274  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
1275  if (myState.myPos > myLane->getLength()) {
1276  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop on lane '" + myLane->getID() + " at position " +
1277  toString(myState.myPos) + " (decel=" + toString(myAcceleration - myState.mySpeed) + "), time="
1278  + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1280  myState.mySpeed = 0;
1281  }
1282  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
1283  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1284  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
1285  while (leftLength > 0 && i != passedLanes.rend()) {
1286  myFurtherLanes.push_back(*i);
1287  leftLength -= (*i)->setPartialOccupation(this, leftLength);
1288  ++i;
1289  }
1290  }
1291  getBestLanes();
1292  // bestLanes need to be updated before lane changing starts
1293  if (getLaneChangeModel().isChangingLanes()) {
1295  }
1296  setBlinkerInformation(); // needs updated bestLanes
1297  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1299  }
1300  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1301  return moved;
1302 }
1303 
1304 
1305 SUMOReal
1306 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
1307  SUMOReal lengths = 0;
1308  const MSLane::VehCont& vehs = l->getVehiclesSecure();
1309  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1310  if ((*i)->getSpeed() < SUMO_const_haltingSpeed) {
1311  foundStopped = true;
1312  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
1313  l->releaseVehicles();
1314  return ret;
1315  }
1316  lengths += (*i)->getVehicleType().getLengthWithGap();
1317  }
1318  l->releaseVehicles();
1319  return l->getLength() - lengths;
1320 }
1321 
1322 
1323 void
1324 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
1325 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1326  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1327  int bla = 0;
1328  if (MSNet::getInstance()->getCurrentTimeStep() == 152000) {
1329  bla = 0;
1330  }
1331  }
1332 #endif
1333 #ifdef HAVE_INTERNAL_LANES
1335  bool hadVehicle = false;
1336  SUMOReal seenSpace = -lengthsInFront;
1337 
1338  bool foundStopped = false;
1339  // compute available space until a stopped vehicle is found
1340  // this is the sum of non-interal lane length minus in-between vehicle lenghts
1341  for (unsigned int i = 0; i < lfLinks.size(); ++i) {
1342  // skip unset links
1343  DriveProcessItem& item = lfLinks[i];
1344  if (item.myLink == 0 || foundStopped) {
1345  item.availableSpace = seenSpace;
1346  item.hadVehicle = hadVehicle;
1347  continue;
1348  }
1349  // get the next lane, determine whether it is an internal lane
1350  const MSLane* approachedLane = item.myLink->getViaLane();
1351  if (approachedLane != 0) {
1352  if (item.myLink->isCrossing()/* && item.myLink->willHaveBlockedFoe()*/) {
1353  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
1354  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1355  } else {
1356  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1357  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1358  }
1359  item.availableSpace = seenSpace;
1360  item.hadVehicle = hadVehicle;
1361  continue;
1362  }
1363  approachedLane = item.myLink->getLane();
1364  const MSVehicle* last = approachedLane->getLastVehicle();
1365  if (last == 0) {
1366  last = approachedLane->getPartialOccupator();
1367  if (last != 0) {
1369  item.availableSpace = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
1370  hadVehicle = true;
1372  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1374  if (last->myHaveToWaitOnNextLink) {
1375  foundStopped = true;
1376  }
1377  } else {
1378  seenSpace += approachedLane->getLength();
1379  item.availableSpace = seenSpace;
1380  }
1381  } else {
1382  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
1383  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
1384  const SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
1385  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
1386  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1387  } else {
1388  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
1389  item.availableSpace = seenSpace;
1390  }
1391  if (last->myHaveToWaitOnNextLink) {
1392  foundStopped = true;
1393  }
1394  hadVehicle = true;
1395  }
1396  item.hadVehicle = hadVehicle;
1397  }
1398 
1399 
1400 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1401  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1402  int bla = 0;
1403  }
1404 #endif
1405  // check which links allow continuation and add pass available to the previous item
1406  for (int i = (int)(lfLinks.size() - 1); i > 0; --i) {
1407  DriveProcessItem& item = lfLinks[i - 1];
1408  const bool opened = item.myLink != 0 && (item.myLink->havePriority() ||
1409  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
1412  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
1413  if (!opened && item.myLink != 0) {
1414  if (i > 1) {
1415  DriveProcessItem& item2 = lfLinks[i - 2];
1416  if (item2.myLink != 0 && item2.myLink->isCont()) {
1417  allowsContinuation = true;
1418  }
1419  }
1420  }
1421  if (allowsContinuation) {
1422  item.availableSpace = lfLinks[i].availableSpace;
1423  }
1424  }
1425 
1426  // find removalBegin
1427  int removalBegin = -1;
1428  for (unsigned int i = 0; hadVehicle && i < lfLinks.size() && removalBegin < 0; ++i) {
1429  // skip unset links
1430  const DriveProcessItem& item = lfLinks[i];
1431  if (item.myLink == 0) {
1432  continue;
1433  }
1434  /*
1435  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1436  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1437  removalBegin = lastLinkToInternal;
1438  }
1439  */
1440 
1441  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
1442  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1443  SUMOReal impatienceCorrection = 0;
1444  /*
1445  if(item.myLink->getState()==LINKSTATE_MINOR) {
1446  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1447  }
1448  */
1449  if (leftSpace < -impatienceCorrection / 10. && item.myLink->isCrossing()) {
1450  removalBegin = i;
1451  }
1452  //removalBegin = i;
1453  }
1454  }
1455  // abort requests
1456  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1457  while (removalBegin < (int)(lfLinks.size())) {
1459  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
1460  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1461  lfLinks[removalBegin].mySetRequest = false;
1462  }
1463  ++removalBegin;
1464  }
1465  }
1466  }
1467 #else
1468  UNUSED_PARAMETER(lengthsInFront);
1469 #endif
1470  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
1471  if ((*i).myLink != 0) {
1472  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
1473  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((size_t)2); // tie braker
1474  }
1475  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1476  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime());
1477  }
1478  }
1479 }
1480 
1481 
1482 void
1484  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1485  if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) {
1486 #ifdef _DEBUG
1487  if (myTraceMoveReminders) {
1488  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
1489  }
1490 #endif
1491  ++rem;
1492  } else {
1493  if (rem->first->notifyEnter(*this, reason)) {
1494 #ifdef _DEBUG
1495  if (myTraceMoveReminders) {
1496  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
1497  }
1498 #endif
1499  ++rem;
1500  } else {
1501 #ifdef _DEBUG
1502  if (myTraceMoveReminders) {
1503  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
1504  }
1505 #endif
1506  rem = myMoveReminders.erase(rem);
1507  }
1508  }
1509  }
1510 }
1511 
1512 
1513 bool
1514 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1515  myAmOnNet = !onTeleporting;
1516  // vaporizing edge?
1517  /*
1518  if (enteredLane->getEdge().isVaporizing()) {
1519  // yep, let's do the vaporization...
1520  myLane = enteredLane;
1521  return true;
1522  }
1523  */
1524  // move mover reminder one lane further
1525  adaptLaneEntering2MoveReminder(*enteredLane);
1526  // set the entered lane as the current lane
1527  myLane = enteredLane;
1528 
1529  // internal edges are not a part of the route...
1530  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1531  ++myCurrEdge;
1532  }
1533  if (!onTeleporting) {
1535  } else {
1537  // normal move() isn't called so reset position here
1538  myState.myPos = 0;
1540  }
1541  return hasArrived();
1542 }
1543 
1544 
1545 void
1547  myAmOnNet = true;
1548  myLane = enteredLane;
1549  // need to update myCurrentLaneInBestLanes
1550  getBestLanes();
1551  // switch to and activate the new lane's reminders
1552  // keep OldLaneReminders
1553  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1554  addReminder(*rem);
1555  }
1557  /*
1558  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1559  (*i)->resetPartialOccupation(this);
1560  }
1561  myFurtherLanes.clear();
1562  */
1563  if (myState.myPos - getVehicleType().getLength() < 0) {
1564  // we have to rebuild "further lanes"
1565  const MSRoute& route = getRoute();
1567  MSLane* lane = myLane;
1568  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1569  while (i != route.begin() && leftLength > 0) {
1570  /* const MSEdge* const prev = */ *(--i);
1571  lane = lane->getLogicalPredecessorLane();
1572  if (lane == 0) {
1573  break;
1574  }
1575  myFurtherLanes.push_back(lane);
1576  leftLength -= (lane)->setPartialOccupation(this, leftLength);
1577  /*
1578  const std::vector<MSLane::IncomingLaneInfo> &incomingLanes = lane->getIncomingLanes();
1579  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = incomingLanes.begin(); j != incomingLanes.end(); ++j) {
1580  if (&(*j).lane->getEdge() == prev) {
1581  #ifdef HAVE_INTERNAL_LANES
1582  (*j).lane->setPartialOccupation(this, leftLength);
1583  #else
1584  leftLength -= (*j).length;
1585  (*j).lane->setPartialOccupation(this, leftLength);
1586  #endif
1587  leftLength -= (*j).lane->getLength();
1588  break;
1589  }
1590  }
1591  */
1592  }
1593  }
1594 }
1595 
1596 
1597 void
1599  myState = State(pos, speed);
1601  assert(myState.myPos >= 0);
1602  assert(myState.mySpeed >= 0);
1603  myWaitingTime = 0;
1604  myLane = enteredLane;
1605  // set and activate the new lane's reminders
1606  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1607  addReminder(*rem);
1608  }
1609  activateReminders(notification);
1610  std::string msg;
1611  if (MSGlobals::gCheckRoutes && !hasValidRoute(msg)) {
1612  throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
1613  }
1614  myAmOnNet = true;
1615  // build the list of lanes the vehicle is lapping into
1616  SUMOReal leftLength = myType->getLength() - pos;
1617  MSLane* clane = enteredLane;
1618  while (leftLength > 0) {
1619  clane = clane->getLogicalPredecessorLane();
1620  if (clane == 0) {
1621  break;
1622  }
1623  myFurtherLanes.push_back(clane);
1624  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1625  }
1626 }
1627 
1628 
1629 void
1631  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1632  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1633 #ifdef _DEBUG
1634  if (myTraceMoveReminders) {
1635  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
1636  }
1637 #endif
1638  ++rem;
1639  } else {
1640 #ifdef _DEBUG
1641  if (myTraceMoveReminders) {
1642  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
1643  }
1644 #endif
1645  rem = myMoveReminders.erase(rem);
1646  }
1647  }
1648  if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) {
1649  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1650  (*i)->resetPartialOccupation(this);
1651  }
1652  myFurtherLanes.clear();
1653  }
1654  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
1655  myAmOnNet = false;
1656  }
1657 }
1658 
1659 
1662  return *myLaneChangeModel;
1663 }
1664 
1665 
1668  return *myLaneChangeModel;
1669 }
1670 
1671 
1672 const std::vector<MSVehicle::LaneQ>&
1673 MSVehicle::getBestLanes(bool forceRebuild, MSLane* startLane) const {
1674 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1675  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1676  int bla = 0;
1677  myLastBestLanesEdge = 0;
1678  }
1679 #endif
1680 
1681  if (startLane == 0) {
1682  startLane = myLane;
1683  }
1684  assert(startLane != 0);
1685  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
1686  std::vector<LaneQ>& lanes = *myBestLanes.begin();
1687  std::vector<LaneQ>::iterator i;
1688  for (i = lanes.begin(); i != lanes.end(); ++i) {
1689  SUMOReal nextOccupation = 0;
1690  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1691  nextOccupation += (*j)->getBruttoVehLenSum();
1692  }
1693  (*i).nextOccupation = nextOccupation;
1694  if ((*i).lane == startLane) {
1696  }
1697  }
1698  return *myBestLanes.begin();
1699  }
1700  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1701  if (myBestLanes.size() == 0 || forceRebuild) {
1702  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
1703  getBestLanes(true, startLane->getLogicalPredecessorLane());
1704  }
1705  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
1706  return *myBestLanes.begin();
1707  }
1708  // adapt best lanes to fit the current internal edge:
1709  // keep the entries that are reachable from this edge
1710  const MSEdge* nextEdge = &(startLane->getLinkCont()[0]->getLane()->getEdge());
1711  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
1712  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
1713  std::vector<LaneQ>& lanes = *it;
1714  assert(lanes.size() > 0);
1715  if (&(lanes[0].lane->getEdge()) == nextEdge) {
1716  // keep those lanes which are successors of internal lanes from the edge of startLane
1717  std::vector<LaneQ> oldLanes = lanes;
1718  lanes.clear();
1719  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
1720  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
1721  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
1722  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
1723  lanes.push_back(*it_lane);
1724  break;
1725  }
1726  }
1727  }
1728  assert(lanes.size() == startLane->getEdge().getLanes().size());
1729  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
1730  for (int i = 0; i < (int)lanes.size(); ++i) {
1731  if (i + lanes[i].bestLaneOffset < 0) {
1732  lanes[i].bestLaneOffset = -i;
1733  }
1734  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
1735  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
1736  }
1737  assert(i + lanes[i].bestLaneOffset >= 0);
1738  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
1739  if (lanes[i].bestContinuations[0] != 0) {
1740  // patch length of bestContinuation to match expectations (only once)
1741  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
1742  }
1743  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
1744  myCurrentLaneInBestLanes = lanes.begin() + i;
1745  }
1746  assert(&(lanes[i].lane->getEdge()) == nextEdge);
1747  }
1748  myLastBestLanesInternalLane = startLane;
1749  return lanes;
1750  } else {
1751  // remove passed edges
1752  it = myBestLanes.erase(it);
1753  }
1754  }
1755  assert(false); // should always find the next edge
1756  }
1757  // start rebuilding
1758  myLastBestLanesEdge = &startLane->getEdge();
1759  myBestLanes.clear();
1760 
1761  // get information about the next stop
1762  const MSEdge* nextStopEdge = 0;
1763  const MSLane* nextStopLane = 0;
1764  SUMOReal nextStopPos = 0;
1765  if (!myStops.empty()) {
1766  const Stop& nextStop = myStops.front();
1767  nextStopLane = nextStop.lane;
1768  nextStopEdge = &nextStopLane->getEdge();
1769  nextStopPos = nextStop.startPos;
1770  }
1771  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
1772  nextStopEdge = *(myRoute->end() - 1);
1773  nextStopLane = nextStopEdge->getLanes()[myParameter->arrivalLane];
1774  nextStopPos = myArrivalPos;
1775  }
1776  if (nextStopEdge != 0) {
1777  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
1778  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
1779  nextStopPos = MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS));
1780  }
1781 
1782  // go forward along the next lanes;
1783  int seen = 0;
1784  SUMOReal seenLength = 0;
1785  bool progress = true;
1786  for (MSRouteIterator ce = myCurrEdge; progress;) {
1787  std::vector<LaneQ> currentLanes;
1788  const std::vector<MSLane*>* allowed = 0;
1789  const MSEdge* nextEdge = 0;
1790  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
1791  nextEdge = *(ce + 1);
1792  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
1793  }
1794  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
1795  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1796  LaneQ q;
1797  MSLane* cl = *i;
1798  q.lane = cl;
1799  q.bestContinuations.push_back(cl);
1800  q.bestLaneOffset = 0;
1801  q.length = cl->getLength();
1802  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
1803  currentLanes.push_back(q);
1804  }
1805  //
1806  if (nextStopEdge == *ce) {
1807  progress = false;
1808  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
1809  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
1810  (*q).allowsContinuation = false;
1811  (*q).length = nextStopPos;
1812  }
1813  }
1814  }
1815 
1816  myBestLanes.push_back(currentLanes);
1817  ++seen;
1818  seenLength += currentLanes[0].lane->getLength();
1819  ++ce;
1820  progress &= (seen <= 4 || seenLength < 3000);
1821  progress &= seen <= 8;
1822  progress &= ce != myRoute->end();
1823  /*
1824  if(progress) {
1825  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
1826  }
1827  */
1828  }
1829 
1830  // we are examining the last lane explicitly
1831  if (myBestLanes.size() != 0) {
1832  SUMOReal bestLength = -1;
1833  int bestThisIndex = 0;
1834  int index = 0;
1835  std::vector<LaneQ>& last = myBestLanes.back();
1836  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1837  if ((*j).length > bestLength) {
1838  bestLength = (*j).length;
1839  bestThisIndex = index;
1840  }
1841  }
1842  index = 0;
1843  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1844  if ((*j).length < bestLength) {
1845  (*j).bestLaneOffset = bestThisIndex - index;
1846  }
1847  }
1848  }
1849 
1850  // go backward through the lanes
1851  // track back best lane and compute the best prior lane(s)
1852  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
1853  std::vector<LaneQ>& nextLanes = (*(i - 1));
1854  std::vector<LaneQ>& clanes = (*i);
1855  MSEdge& cE = clanes[0].lane->getEdge();
1856  int index = 0;
1857  SUMOReal bestConnectedLength = -1;
1858  SUMOReal bestLength = -1;
1859  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
1860  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
1861  bestConnectedLength = (*j).length;
1862  }
1863  if (bestLength < (*j).length) {
1864  bestLength = (*j).length;
1865  }
1866  }
1867  // compute index of the best lane (highest length and least offset from the best next lane)
1868  int bestThisIndex = 0;
1869  if (bestConnectedLength > 0) {
1870  index = 0;
1871  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1872  LaneQ bestConnectedNext;
1873  bestConnectedNext.length = -1;
1874  if ((*j).allowsContinuation) {
1875  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
1876  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1877  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
1878  bestConnectedNext = *m;
1879  }
1880  }
1881  }
1882  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
1883  (*j).length += bestLength;
1884  } else {
1885  (*j).length += bestConnectedNext.length;
1886  }
1887  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
1888  }
1889  if (clanes[bestThisIndex].length < (*j).length || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))) {
1890  bestThisIndex = index;
1891  }
1892  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
1893  }
1894 
1895  } else {
1896  int bestNextIndex = 0;
1897  int bestDistToNeeded = (int) clanes.size();
1898  index = 0;
1899  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1900  if ((*j).allowsContinuation) {
1901  int nextIndex = 0;
1902  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
1903  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1904  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
1905  bestDistToNeeded = abs((*m).bestLaneOffset);
1906  bestThisIndex = index;
1907  bestNextIndex = nextIndex;
1908  }
1909  }
1910  }
1911  }
1912  }
1913  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
1914  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
1915 
1916  }
1917  // set bestLaneOffset for all lanes
1918  index = 0;
1919  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1920  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))) {
1921  (*j).bestLaneOffset = bestThisIndex - index;
1922  } else {
1923  (*j).bestLaneOffset = 0;
1924  }
1925  }
1926  }
1927 
1928  // update occupancy and current lane index
1929  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
1930  std::vector<LaneQ>::iterator i;
1931  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
1932  SUMOReal nextOccupation = 0;
1933  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1934  nextOccupation += (*j)->getBruttoVehLenSum();
1935  }
1936  (*i).nextOccupation = nextOccupation;
1937  if ((*i).lane == startLane) {
1939  }
1940  }
1941  return *myBestLanes.begin();
1942 }
1943 
1944 
1945 const std::vector<MSLane*>&
1947  if (myBestLanes.empty() || myBestLanes[0].empty()) {
1948  return myEmptyLaneVector;
1949  }
1950  return (*myCurrentLaneInBestLanes).bestContinuations;
1951 }
1952 
1953 
1954 const std::vector<MSLane*>&
1956  const MSLane* lane = l;
1958  // internal edges are not kept inside the bestLanes structure
1959  lane = lane->getLinkCont()[0]->getLane();
1960  }
1961  if (myBestLanes.size() == 0) {
1962  return myEmptyLaneVector;
1963  }
1964  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
1965  if ((*i).lane == lane) {
1966  return (*i).bestContinuations;
1967  }
1968  }
1969  return myEmptyLaneVector;
1970 }
1971 
1972 
1973 int
1975  if (myBestLanes.empty() || myBestLanes[0].empty()) {
1976  return 0;
1977  } else {
1978  return (*myCurrentLaneInBestLanes).bestLaneOffset;
1979  }
1980 }
1981 
1982 
1983 bool
1985  if (getPositionOnLane() > myLane->getLength()) {
1988  return true;
1989  }
1990  return false;
1991 }
1992 
1993 
1994 SUMOReal
1996 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1997  SUMOReal distance = 1000000.;
1998 #else
2000 #endif
2001  if (isOnRoad() && destEdge != NULL) {
2002  if (&myLane->getEdge() == *myCurrEdge) {
2003  // vehicle is on a normal edge
2004  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
2005  } else {
2006  // vehicle is on inner junction edge
2007  distance = myLane->getLength() - getPositionOnLane();
2008  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
2009  }
2010  }
2011  return distance;
2012 }
2013 
2014 
2015 SUMOReal
2018 }
2019 
2020 
2021 SUMOReal
2024 }
2025 
2026 
2027 SUMOReal
2030 }
2031 
2032 
2033 SUMOReal
2036 }
2037 
2038 
2039 SUMOReal
2042 }
2043 
2044 
2045 SUMOReal
2048 }
2049 
2050 
2051 SUMOReal
2054 }
2055 
2056 
2057 void
2059  if (myPersonDevice == 0) {
2061  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
2062  }
2063  myPersonDevice->addPerson(person);
2064  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
2065  unsigned int numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2066  if (numExpected != 0) {
2067  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
2068  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
2069  // Bus drivers usually do not know the names of the passengers.
2070  myStops.front().awaitedPersons.erase(person->getID());
2071  numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2072  }
2073  if (numExpected == 0) {
2074  myStops.front().duration = 0;
2075  }
2076  }
2077 }
2078 
2079 
2080 unsigned int
2082  unsigned int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
2083  return boarded + myParameter->personNumber;
2084 }
2085 
2086 
2087 void
2090  int state = getLaneChangeModel().getOwnState();
2091  if ((state & LCA_LEFT) != 0) {
2093  } else if ((state & LCA_RIGHT) != 0) {
2095  } else {
2096  const MSLane* lane = getLane();
2097  MSLinkCont::const_iterator link = lane->succLinkSec(*this, 1, *lane, getBestLanesContinuation());
2098  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
2099  switch ((*link)->getDirection()) {
2100  case LINKDIR_TURN:
2101  case LINKDIR_LEFT:
2102  case LINKDIR_PARTLEFT:
2104  break;
2105  case LINKDIR_RIGHT:
2106  case LINKDIR_PARTRIGHT:
2108  break;
2109  default:
2110  break;
2111  }
2112  }
2113  }
2114 
2115 }
2116 
2117 
2118 void
2120  if (myType->amVehicleSpecific()) {
2121  delete myType;
2122  }
2123  myType = type;
2124 }
2125 
2126 unsigned int
2128  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
2129  return (unsigned int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
2130 }
2131 
2132 
2133 SUMOReal
2135  return MAX2((SUMOReal)0, MIN2((SUMOReal)1, getVehicleType().getImpatience() +
2137 }
2138 
2139 
2140 #ifndef NO_TRACI
2141 bool
2142 MSVehicle::addTraciStop(MSLane* lane, SUMOReal pos, SUMOReal /*radius*/, SUMOTime duration, bool parking, bool triggered) {
2143  //if the stop exists update the duration
2144  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2145  if (iter->lane == lane && fabs(iter->endPos - pos) < POSITION_EPS) {
2146  if (duration == 0 && !iter->reached) {
2147  myStops.erase(iter);
2148  } else {
2149  iter->duration = duration;
2150  }
2151  return true;
2152  }
2153  }
2154 
2156  newStop.lane = lane->getID();
2157  newStop.busstop = MSNet::getInstance()->getBusStopID(lane, pos);
2158  newStop.startPos = pos - POSITION_EPS;
2159  newStop.endPos = pos;
2160  newStop.duration = duration;
2161  newStop.until = -1;
2162  newStop.triggered = triggered;
2163  newStop.parking = parking;
2164  newStop.index = STOP_INDEX_FIT;
2165  return addStop(newStop);
2166 }
2167 
2168 
2169 bool
2171  Stop& stop = myStops.front();
2172  if (!stop.reached) {
2173  return false;
2174  }
2175  stop.duration = 0;
2176  return true;
2177 }
2178 
2179 
2182  return myStops.front();
2183 }
2184 
2185 
2188  if (myInfluencer == 0) {
2189  myInfluencer = new Influencer();
2190  }
2191  return *myInfluencer;
2192 }
2193 
2194 
2195 SUMOReal
2197  if (myInfluencer != 0) {
2198  return myInfluencer->getOriginalSpeed();
2199  }
2200  return myState.mySpeed;
2201 }
2202 
2203 
2204 int
2206  if (hasInfluencer()) {
2208  MSNet::getInstance()->getCurrentTimeStep(),
2209  myLane->getEdge(),
2210  getLaneIndex(),
2211  state);
2212  }
2213  return state;
2214 }
2215 #endif
2216 
2217 
2218 void
2221  // here starts the vehicle internal part (see loading)
2222  std::vector<int> internals;
2223  internals.push_back(myDeparture);
2224  internals.push_back((int)distance(myRoute->begin(), myCurrEdge));
2225  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
2228  out.closeTag();
2229 }
2230 
2231 
2232 void
2233 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
2234  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
2235  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
2236  }
2237  unsigned int routeOffset;
2238  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
2239  bis >> myDeparture;
2240  bis >> routeOffset;
2241  if (hasDeparted()) {
2242  myDeparture -= offset;
2243  myCurrEdge += routeOffset;
2244  }
2247  // no need to reset myCachedPosition here since state loading happens directly after creation
2248 }
2249 
2250 
2251 /****************************************************************************/