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.sourceforge.net/
20 // Copyright (C) 2001-2012 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 "MSLane.h"
41 #include "MSVehicle.h"
42 #include "MSEdge.h"
43 #include "MSVehicleType.h"
44 #include "MSNet.h"
45 #include "MSRoute.h"
46 #include "MSLinkCont.h"
48 #include <utils/common/StdDefs.h>
50 #include <microsim/MSGlobals.h>
51 #include <iostream>
52 #include <cassert>
53 #include <cmath>
54 #include <cstdlib>
55 #include <algorithm>
56 #include <map>
57 #include "MSMoveReminder.h"
59 #include "MSLCM_DK2004.h"
60 #include <utils/common/ToString.h>
64 #include "trigger/MSBusStop.h"
66 #include "MSPerson.h"
67 #include "MSPersonControl.h"
70 #include "MSEdgeWeightsStorage.h"
73 
74 #ifdef _MESSAGES
75 #include "MSMessageEmitter.h"
76 #endif
77 
78 #ifdef HAVE_INTERNAL
79 #include <mesosim/MESegment.h>
80 #include <mesosim/MELoop.h>
81 #include "MSGlobals.h"
82 #endif
83 
84 #ifdef CHECK_MEMORY_LEAKS
85 #include <foreign/nvwa/debug_new.h>
86 #endif // CHECK_MEMORY_LEAKS
87 
88 //#define DEBUG_VEHICLE_GUI_SELECTION 1
89 #ifdef DEBUG_VEHICLE_GUI_SELECTION
90 #undef ID_LIST
92 #include <guisim/GUIVehicle.h>
93 #include <guisim/GUILane.h>
94 #endif
95 
96 #define BUS_STOP_OFFSET 0.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), myConsiderSafeVelocity(true),
148  myConsiderMaxAcceleration(true), myConsiderMaxDeceleration(true) {}
149 
150 
152 
153 
154 void
155 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
156  mySpeedAdaptationStarted = true;
157  mySpeedTimeLine = speedTimeLine;
158 }
159 
160 
161 void
162 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, unsigned int> >& laneTimeLine) {
163  myLaneTimeLine = laneTimeLine;
164 }
165 
166 
167 SUMOReal
169  // keep original speed
170  myOriginalSpeed = speed;
171  // remove leading commands which are no longer valid
172  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
173  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
174  }
175  // do nothing if the time line does not apply for the current time
176  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
177  return speed;
178  }
179  // compute and set new speed
180  if (!mySpeedAdaptationStarted) {
181  mySpeedTimeLine[0].second = speed;
182  mySpeedAdaptationStarted = true;
183  }
184  currentTime += DELTA_T;
185  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
186  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
187  if (myConsiderSafeVelocity) {
188  speed = MIN2(speed, vSafe);
189  }
190  if (myConsiderMaxAcceleration) {
191  speed = MIN2(speed, vMax);
192  }
193  if (myConsiderMaxDeceleration) {
194  speed = MAX2(speed, vMin);
195  }
196  return speed;
197 }
198 
199 
201 MSVehicle::Influencer::checkForLaneChanges(SUMOTime currentTime, const MSEdge& currentEdge, unsigned int currentLaneIndex) {
202  // remove leading commands which are no longer valid
203  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
204  myLaneTimeLine.erase(myLaneTimeLine.begin());
205  }
206  // do nothing if the time line does not apply for the current time
207  if (myLaneTimeLine.size() < 2 || currentTime < myLaneTimeLine[0].first) {
208  return REQUEST_NONE;
209  }
210  unsigned int destinationLaneIndex = myLaneTimeLine[1].second;
211  if ((unsigned int)currentEdge.getLanes().size() <= destinationLaneIndex) {
212  return REQUEST_NONE;
213  }
214  if (currentLaneIndex > destinationLaneIndex) {
215  return REQUEST_RIGHT;
216  } else if (currentLaneIndex < destinationLaneIndex) {
217  return REQUEST_LEFT;
218  } else {
219  return REQUEST_HOLD;
220  }
221 }
222 
223 
224 void
226  myConsiderSafeVelocity = value;
227 }
228 
229 
230 void
232  myConsiderMaxAcceleration = value;
233 }
234 
235 
236 void
238  myConsiderMaxDeceleration = value;
239 }
240 #endif
241 
242 
243 /* -------------------------------------------------------------------------
244  * MSVehicle-methods
245  * ----------------------------------------------------------------------- */
247  delete myLaneChangeModel;
248  // other
249  delete myEdgeWeights;
250  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
251  (*i)->resetPartialOccupation(this);
252  }
253  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
254  if ((*i).myLink != 0) {
255  (*i).myLink->removeApproaching(this);
256  }
257  }
258  myFurtherLanes.clear();
259  //
260  if (myType->amVehicleSpecific()) {
261  delete myType;
262  }
263 #ifndef NO_TRACI
264  delete myInfluencer;
265 #endif
266 }
267 
268 
270  const MSRoute* route,
271  const MSVehicleType* type,
272  SUMOReal speedFactor,
273  int /*vehicleIndex*/) :
274  MSBaseVehicle(pars, route, type, speedFactor),
276  myWaitingTime(0),
277  myState(0, 0), //
278  myLane(0),
280  myPersonDevice(0),
281  myAcceleration(0),
282  mySignals(0),
283  myAmOnNet(false),
285  myHaveToWaitOnNextLink(false),
286  myEdgeWeights(0)
287 #ifndef NO_TRACI
288  , myInfluencer(0)
289 #endif
290 {
291  for (std::vector<SUMOVehicleParameter::Stop>::iterator i = pars->stops.begin(); i != pars->stops.end(); ++i) {
292  if (!addStop(*i)) {
293  throw ProcessError("Stop for vehicle '" + pars->id +
294  "' on lane '" + i->lane + "' is not downstream the current route.");
295  }
296  }
297  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = route->getStops().begin(); i != route->getStops().end(); ++i) {
298  if (!addStop(*i)) {
299  throw ProcessError("Stop for vehicle '" + pars->id +
300  "' on lane '" + i->lane + "' is not downstream the current route.");
301  }
302  }
303  const MSLane* const depLane = (*myCurrEdge)->getDepartLane(*this);
304  if (depLane == 0) {
305  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
306  }
307  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > depLane->getSpeedLimit()) {
308  throw ProcessError("Departure speed for vehicle '" + pars->id +
309  "' is too high for the departure lane '" + depLane->getID() + "'.");
310  }
311  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
312  throw ProcessError("Departure speed for vehicle '" + pars->id +
313  "' is too high for the vehicle type '" + type->getID() + "'.");
314  }
315 #ifdef _MESSAGES
316  myLCMsgEmitter = MSNet::getInstance()->getMsgEmitter("lanechange");
317  myBMsgEmitter = MSNet::getInstance()->getMsgEmitter("break");
318  myHBMsgEmitter = MSNet::getInstance()->getMsgEmitter("heartbeat");
319 #endif
320  myLaneChangeModel = new MSLCM_DK2004(*this);
322 }
323 
324 
325 void
328  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
329  if ((*i).myLink != 0) {
330  (*i).myLink->removeApproaching(this);
331  }
332  }
333  leaveLane(reason);
334 }
335 
336 
337 // ------------ interaction with the route
338 bool
340  return myCurrEdge == myRoute->end() - 1 && myState.myPos > myArrivalPos - POSITION_EPS;
341 }
342 
343 
344 bool
345 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit) {
346  const MSEdgeVector& edges = newRoute->getEdges();
347  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
348  if (!onInit && !newRoute->contains(*myCurrEdge)) {
349  return false;
350  }
351 
352  // rebuild in-vehicle route information
353  if (onInit) {
354  myCurrEdge = newRoute->begin();
355  } else {
356  myCurrEdge = find(edges.begin(), edges.end(), *myCurrEdge);
357  }
358  // check whether the old route may be deleted (is not used by anyone else)
359  newRoute->addReference();
360  myRoute->release();
361  // assign new route
362  myRoute = newRoute;
364  // update arrival definition
366  // save information that the vehicle was rerouted
369  // recheck stops
370  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
371  if (find(edges.begin(), edges.end(), &iter->lane->getEdge()) == edges.end()) {
372  iter = myStops.erase(iter);
373  } else {
374  iter->edge = find(edges.begin(), edges.end(), &iter->lane->getEdge());
375  ++iter;
376  }
377  }
378  return true;
379 }
380 
381 
382 bool
383 MSVehicle::willPass(const MSEdge* const edge) const {
384  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
385 }
386 
387 
388 unsigned int
390  return (unsigned int) std::distance(myRoute->begin(), myCurrEdge);
391 }
392 
393 
394 void
395 MSVehicle::resetRoutePosition(unsigned int index) {
396  myCurrEdge = myRoute->begin() + index;
397  // !!! hack
398  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
399 }
400 
401 
402 
405  return _getWeightsStorage();
406 }
407 
408 
411  return _getWeightsStorage();
412 }
413 
414 
417  if (myEdgeWeights == 0) {
419  }
420  return *myEdgeWeights;
421 }
422 
423 
424 // ------------ Interaction with move reminders
425 void
427  // This erasure-idiom works for all stl-sequence-containers
428  // See Meyers: Effective STL, Item 9
429  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
430  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
431  rem = myMoveReminders.erase(rem);
432  } else {
433  ++rem;
434  }
435  }
436 }
437 
438 
439 void
441  // save the old work reminders, patching the position information
442  // add the information about the new offset to the old lane reminders
443  const SUMOReal oldLaneLength = myLane->getLength();
444  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
445  rem->second += oldLaneLength;
446  }
447  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
448  addReminder(*rem);
449  }
450 }
451 
452 
453 // ------------ Other getter methods
454 Position
456  if (myLane == 0) {
457  return Position(-1000, -1000);
458  }
460 }
461 
462 
463 SUMOReal
466  Position p2 = myFurtherLanes.size() > 0
467  ? myFurtherLanes.back()->getShape().positionAtLengthPosition(myFurtherLanes.back()->getPartialOccupatorEnd())
469  if (p1 != p2) {
470  return atan2(p1.x() - p2.x(), p2.y() - p1.y()) * 180. / PI;
471  } else {
473  }
474 }
475 
476 
477 // ------------
478 bool
480  Stop stop;
481  stop.lane = MSLane::dictionary(stopPar.lane);
482  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
483  stop.startPos = stopPar.startPos;
484  stop.endPos = stopPar.endPos;
485  stop.duration = stopPar.duration;
486  stop.until = stopPar.until;
487  if (stop.until != -1) {
488  stop.until += untilOffset;
489  }
490  stop.triggered = stopPar.triggered;
491  stop.parking = stopPar.parking;
492  stop.reached = false;
493  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
494  return false;
495  }
496  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
497  MSRouteIterator prevStopEdge = myCurrEdge;
498  SUMOReal prevStopPos = myState.myPos;
499  // where to insert the stop
500  std::list<Stop>::iterator iter = myStops.begin();
501  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
502  if (myStops.size() > 0) {
503  prevStopEdge = myStops.back().edge;
504  prevStopPos = myStops.back().endPos;
505  iter = myStops.end();
506  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
507  }
508  } else {
509  if (stopPar.index == STOP_INDEX_FIT) {
510  while (iter != myStops.end() && (iter->edge < stop.edge ||
511  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
512  prevStopEdge = iter->edge;
513  prevStopPos = iter->endPos;
514  ++iter;
515  }
516  } else {
517  int index = stopPar.index;
518  while (index > 0) {
519  prevStopEdge = iter->edge;
520  prevStopPos = iter->endPos;
521  ++iter;
522  --index;
523  }
524  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
525  }
526  }
527  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
528  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
529  return false;
530  }
532  return false;
533  }
534  myStops.insert(iter, stop);
535  return true;
536 }
537 
538 
539 bool
541  return !myStops.empty() && myStops.begin()->reached;
542 }
543 
544 
545 bool
547  return isStopped() && myStops.begin()->parking;
548 }
549 
550 
551 SUMOReal
553  if (myStops.empty()) {
554  // no stops; pass
555  return currentVelocity;
556  }
557  Stop& stop = myStops.front();
558  if (stop.reached) {
559  // ok, we have already reached the next stop
560  // any waiting persons may board now
561  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this);
562  if (boarded) {
563  if (stop.busstop != 0) {
564  const std::vector<MSPerson*>& persons = myPersonDevice->getPersons();
565  for (std::vector<MSPerson*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
566  stop.busstop->removePerson(*i);
567  }
568  }
569  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
570  stop.triggered = false;
574  }
575  }
576  if (stop.duration <= 0 && !stop.triggered) {
577  // we have waited long enough and fulfilled any passenger-requirements
578  if (stop.busstop != 0) {
579  // inform bus stop about leaving it
580  stop.busstop->leaveFrom(this);
581  }
582  // the current stop is no longer valid
584  myStops.pop_front();
585  // do not count the stopping time towards gridlock time.
586  // Other outputs use an independent counter and are not affected.
587  myWaitingTime = 0;
588  // maybe the next stop is on the same edge; let's rebuild best lanes
589  getBestLanes(true);
590  // continue as wished...
591  } else {
592  // we have to wait some more time
594  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
597  }
598  stop.duration -= DELTA_T;
599  return 0;
600  }
601  } else {
602  // is the next stop on the current lane?
603  if (stop.edge == myCurrEdge) {
604  // get the stopping position
605  SUMOReal endPos = stop.endPos;
606  bool busStopsMustHaveSpace = true;
607  if (stop.busstop != 0) {
608  // on bus stops, we have to wait for free place if they are in use...
609  endPos = stop.busstop->getLastFreePos(*this);
610  if (endPos - 5. < stop.busstop->getBeginLanePosition()) { // !!! explicit offset
611  busStopsMustHaveSpace = false;
612  }
613  }
614  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace) {
615  // ok, we may stop (have reached the stop)
616  stop.reached = true;
618  // compute stopping time
619  if (stop.until >= 0) {
620  if (stop.duration == -1) {
622  } else {
624  }
625  }
626  if (stop.busstop != 0) {
627  // let the bus stop know the vehicle
629  }
630  }
631  // decelerate
632  return getCarFollowModel().stopSpeed(this, endPos - myState.pos());
633  }
634  }
635  return currentVelocity;
636 }
637 
638 
639 void
640 MSVehicle::move(SUMOTime t, MSLane* lane, MSVehicle* pred, MSVehicle* neigh, SUMOReal lengthsInFront) {
641 #ifdef _MESSAGES
642  if (myHBMsgEmitter != 0) {
643  if (isOnRoad()) {
645  myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
646  }
647  }
648 #endif
649 #ifdef DEBUG_VEHICLE_GUI_SELECTION
650  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
651  int bla = 0;
652  }
653 #endif
654  // remove information about approaching links, will be reset later in this step
655  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
656  if ((*i).myLink != 0) {
657  (*i).myLink->removeApproaching(this);
658  }
659  }
660  myLFLinkLanes.clear();
661  //
662  const MSCFModel& cfModel = getCarFollowModel();
663  // vBeg is the initial maximum velocity of this vehicle in this step
664  SUMOReal v = MIN2(cfModel.maxNextSpeed(myState.mySpeed), lane->getVehicleMaxSpeed(this));
665 #ifndef NO_TRACI
666  if (myInfluencer != 0) {
667  SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
669  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, vMax);
670  // !!! recheck - why is it done, here?
671  }
672 #endif
673 
674  SUMOReal vehicleLength = getVehicleType().getLength();
675  SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed);
676  SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
677  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
678 #ifdef HAVE_INTERNAL_LANES
679  bool hadNonInternal = false;
680 #else
681  bool hadNonInternal = true;
682 #endif
683  SUMOReal seen = lane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
684  SUMOReal seenNonInternal = 0;
685  cfModel.leftVehicleVsafe(this, neigh, v);
686  unsigned int view = 0;
687  bool firstLane = true;
688  int lastLink = -1;
689  std::pair<MSVehicle*, SUMOReal> leaderInfo = pred != 0 ? std::pair<MSVehicle*, SUMOReal>(pred, gap2pred(*pred)) : std::pair<MSVehicle*, SUMOReal>((MSVehicle*) 0, 0);
690  while (true) {
691  SUMOReal laneStopOffset = lane->getLength() > getVehicleType().getMinGap() ? getVehicleType().getMinGap() : POSITION_EPS;
692  SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
693  // check leader on lane
694  // leader is given for the first edge only
695  if (!firstLane) {
696  leaderInfo = lane->getLastVehicleInformation();
697  leaderInfo.second = leaderInfo.second + seen - lane->getLength() - getVehicleType().getMinGap();
698  } else if (leaderInfo.first == 0) {
699  // we still have to account vehicles lapping into the lane we are currently at
700  if (myLane->getPartialOccupator() != 0) {
701  leaderInfo = std::pair<MSVehicle*, SUMOReal>(myLane->getPartialOccupator(), myLane->getPartialOccupatorEnd() - myState.myPos - getVehicleType().getMinGap());
702  }
703  }
704  if (leaderInfo.first != 0) {
705  SUMOReal vsafeLeader = 0;
706  if (leaderInfo.second >= 0) {
707  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
708  } else {
709  // the leading, in-lapping vehicle is occupying the complete next lane
710  // stop before entering this lane
711  vsafeLeader = cfModel.stopSpeed(this, seen - lane->getLength() - POSITION_EPS);
712  }
713  if (lastLink > 0) {
714  myLFLinkLanes[lastLink].adaptLeaveSpeed(vsafeLeader);
715  }
716  v = MIN2(v, vsafeLeader);
717  }
718 
719  // process stops
720  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
721  // we are approaching a stop on the edge; must not drive further
722  const Stop& stop = *myStops.begin();
723  SUMOReal stopDist = stop.busstop == 0 ? seen + stop.endPos - lane->getLength() : seen + stop.busstop->getLastFreePos(*this) - POSITION_EPS - lane->getLength();
724  SUMOReal stopSpeed = cfModel.stopSpeed(this, stopDist);
725  if (lastLink > 0) {
726  myLFLinkLanes[lastLink].adaptLeaveSpeed(stopSpeed);
727  }
728  v = MIN2(v, stopSpeed);
729  myLFLinkLanes.push_back(DriveProcessItem(0, v, v, false, 0, 0, stopDist));
730  break;
731  }
732 
733  // move to next lane
734  // get the next link used
735  MSLinkCont::const_iterator link = myLane->succLinkSec(*this, view + 1, *lane, bestLaneConts);
736  // check whether the vehicle is on its final edge
737  bool onAppropriateLane = !lane->isLinkEnd(link); // !!! wird "appropriate" noch benutzt?
738  bool routeEnds = myCurrEdge + view + 1 == myRoute->end();
739  if (routeEnds) {
742  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), seen + myArrivalPos - lane->getLength(), arrivalSpeed);
743  v = MIN2(v, va);
744  if (lastLink > 0) {
745  myLFLinkLanes[lastLink].adaptLeaveSpeed(va);
746  }
747  myLFLinkLanes.push_back(DriveProcessItem(0, v, v, false, 0, 0, seen));
748  break;
749  }
750  // check whether the lane is a dead end
751  if (!onAppropriateLane) {
752  if (!routeEnds) {
753  SUMOReal va = MIN2(cfModel.stopSpeed(this, stopDist), lane->getVehicleMaxSpeed(this));
754  if (lastLink > 0) {
755  myLFLinkLanes[lastLink].adaptLeaveSpeed(va);
756  }
757  v = MIN2(va, v);
758  }
759  myLFLinkLanes.push_back(DriveProcessItem(0, v, v, false, 0, 0, seen));
760  break;
761  }
762 
763  bool yellow = (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR || (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
764  bool red = (*link)->getState() == LINKSTATE_TL_RED;
765  bool setRequest = v > 0; // even if red, if we cannot break we should issue a request
766  SUMOReal vLinkPass = v;
767  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, stopDist));
768  if ((yellow || red) && seen > cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime()) {
769  // the vehicle is able to brake in front of a yellow/red traffic light
770  myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / vLinkPass), vLinkPass, stopDist));
771  break;
772  }
773  SUMOReal va = firstLane ? v : lane->getVehicleMaxSpeed(this);
774  if (lastLink > 0) {
775  myLFLinkLanes[lastLink].adaptLeaveSpeed(va);
776  } //if(!myLFLinkLanes.empty()) { myLFLinkLanes.back().accelV = va; }
777  lastLink = (int)myLFLinkLanes.size();
778  myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkPass, vLinkWait, setRequest, t + TIME2STEPS(seen / vLinkPass), vLinkPass, stopDist));
779 
780  // get the following lane
781  lane = (*link)->getViaLaneOrLane();
782 #ifdef HAVE_INTERNAL_LANES
783  if ((*link)->getViaLane() == 0) {
784  hadNonInternal = true;
785  ++view;
786  }
787 #else
788  ++view;
789 #endif
790  // estimate leave speed for passing time computation
791  SUMOReal v1 = 2 * (*link)->getLength() * getVehicleType().getCarFollowModel().getMaxAccel() + vLinkPass;
792  SUMOReal leaveSpeed = MIN2(lane->getVehicleMaxSpeed(this), (SUMOReal)sqrt(v1));
793  myLFLinkLanes[lastLink].adaptLeaveSpeed(leaveSpeed);
794 
795  firstLane = false;
796  if (!setRequest || ((vLinkPass <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * 2)) {
797  break;
798  }
799  // the link was passed
800  // compute the velocity to use when the link is not blocked by other vehicles
801  // the vehicle shall be not faster when reaching the next lane than allowed
802  va = MAX2(lane->getVehicleMaxSpeed(this), cfModel.freeSpeed(this, getSpeed(), seen, lane->getVehicleMaxSpeed(this)));
803  v = MIN2(va, vLinkPass);
804  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
805  seen += lane->getLength();
806  }
807  checkRewindLinkLanes(lengthsInFront);
808 }
809 
810 
811 bool
813 #ifdef DEBUG_VEHICLE_GUI_SELECTION
814  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
815  int bla = 0;
816  }
817 #endif
818  // get vsafe
819  SUMOReal vSafe = 0;
820  myHaveToWaitOnNextLink = false;
821 
822  assert(myLFLinkLanes.size() != 0);
823  DriveItemVector::iterator i;
824  bool braking = false;
825  bool lastWasGreenCont = false;
826  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
827  MSLink* link = (*i).myLink;
828  // the vehicle must change the lane on one of the next lanes
829  if (link != 0 && (*i).mySetRequest) {
830  const LinkState ls = link->getState();
831  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
832  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
834  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
835  vSafe = (*i).myVLinkWait;
836  braking = true;
837  lastWasGreenCont = false;
838  link->removeApproaching(this);
839  break;
840  }
841  //
842  const bool opened = yellow || link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(), getVehicleType().getLengthWithGap());
843  // vehicles should decelerate when approaching a minor link
844  if (opened && !lastWasGreenCont && !link->havePriority() && (*i).myDistance > getCarFollowModel().getMaxDecel()) {
845  vSafe = (*i).myVLinkWait;
846  braking = true;
847  lastWasGreenCont = false;
848  if (ls == LINKSTATE_EQUAL) {
849  link->removeApproaching(this);
850  }
851  break; // could be revalidated
852  }
853  // have waited; may pass if opened...
854  if (opened) {
855  vSafe = (*i).myVLinkPass;
856  lastWasGreenCont = link->isCont() && (ls == LINKSTATE_TL_GREEN_MAJOR);
857  } else {
858  lastWasGreenCont = false;
859  vSafe = (*i).myVLinkWait;
860  braking = true;
861  if (ls == LINKSTATE_EQUAL) {
862  link->removeApproaching(this);
863  }
864  break;
865  }
866  } else {
867  vSafe = (*i).myVLinkWait;
868  braking = true;
869  break;
870  }
871  }
872  if (braking) {
873  myHaveToWaitOnNextLink = true;
874  }
875 
876  SUMOReal vNext = getCarFollowModel().moveHelper(this, vSafe);
877  vNext = MAX2(vNext, (SUMOReal) 0.);
878 #ifndef NO_TRACI
879  if (myInfluencer != 0) {
880  SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
882  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
883  }
884 #endif
885  // visit waiting time
886  if (vNext <= 0.1) {
888  braking = true;
889  } else {
890  myWaitingTime = 0;
891  }
892  if (myState.mySpeed < vNext) {
893  braking = false;
894  }
895  if (braking) {
897  } else {
899  }
900  // call reminders after vNext is set
901  SUMOReal pos = myState.myPos;
902  vNext = MIN2(vNext, getMaxSpeed());
903 
904 #ifdef _MESSAGES
905  if (myHBMsgEmitter != 0) {
906  if (isOnRoad()) {
908  myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
909  }
910  }
911  if (myBMsgEmitter != 0) {
912  if (vNext < myState.mySpeed) {
914  myBMsgEmitter->writeBreakEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
915  }
916  }
917 #endif
918  // update position and speed
919  myAcceleration = vNext - myState.mySpeed;
920  myState.myPos += SPEED2DIST(vNext);
921  myState.mySpeed = vNext;
922  std::vector<MSLane*> passedLanes;
923  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
924  passedLanes.push_back(*i);
925  }
926  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
927  passedLanes.push_back(myLane);
928  }
929  bool moved = false;
930  // move on lane(s)
931  if (myState.myPos <= myLane->getLength()) {
932  // we are staying at our lane
933  // there is no need to go over succeeding lanes
934  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
935  } else {
936  // we are moving at least to the next lane (maybe pass even more than one)
937  if (myCurrEdge != myRoute->end() - 1) {
938  MSLane* approachedLane = myLane;
939  // move the vehicle forward
940  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
942  MSLink* link = (*i).myLink;
943  // check whether the vehicle was allowed to enter lane
944  // otherwise it is decelareted and we do not need to test for it's
945  // approach on the following lanes when a lane changing is performed
946  // proceed to the next lane
947  if (link != 0) {
948  approachedLane = link->getViaLaneOrLane();
949  } else {
950  approachedLane = 0;
951  }
952  if (approachedLane != myLane && approachedLane != 0) {
954  assert(myState.myPos > 0);
955  enterLaneAtMove(approachedLane);
956  myLane = approachedLane;
957  moved = true;
958  if (approachedLane->getEdge().isVaporizing()) {
959  break;
960  }
961  }
962  passedLanes.push_back(approachedLane);
963  }
964  }
965  }
966  // clear previously set information
967  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
968  (*i)->resetPartialOccupation(this);
969  }
970  myFurtherLanes.clear();
971  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
972  if (myState.myPos > myLane->getLength()) {
973  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop one lane '" + myLane->getID() + " at position " +
974  toString(myState.myPos) + " (decel=" + toString(myAcceleration - myState.mySpeed) + "), time="
975  + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
977  myState.mySpeed = 0;
978  }
979  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
980  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
981  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
982  while (leftLength > 0 && i != passedLanes.rend()) {
983  myFurtherLanes.push_back(*i);
984  leftLength -= (*i)->setPartialOccupation(this, leftLength);
985  ++i;
986  }
987  }
989  }
990  return moved;
991 }
992 
993 
994 SUMOReal
996  SUMOReal lengths = 0;
997  const MSLane::VehCont& vehs = l->getVehiclesSecure();
998  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
999  if ((*i)->getSpeed() < .1) {
1000  foundStopped = true;
1001  SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
1002  l->releaseVehicles();
1003  return ret;
1004  }
1005  lengths += (*i)->getVehicleType().getLengthWithGap();
1006  }
1007  l->releaseVehicles();
1008  return l->getLength() - lengths;
1009 }
1010 
1011 
1012 void
1014 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1015  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1016  int bla = 0;
1017  if (MSNet::getInstance()->getCurrentTimeStep() == 152000) {
1018  bla = 0;
1019  }
1020  }
1021 #endif
1022 #ifdef HAVE_INTERNAL_LANES
1024  int removalBegin = -1;
1025  bool hadVehicle = false;
1026  SUMOReal seenSpace = -lengthsInFront;
1027 
1028  std::vector<SUMOReal> availableSpace;
1029  std::vector<bool> hadVehicles;
1030  bool foundStopped = false;
1031 
1032  for (unsigned int i = 0; i < myLFLinkLanes.size(); ++i) {
1033  // skip unset links
1034  DriveProcessItem& item = myLFLinkLanes[i];
1035  if (item.myLink == 0 || foundStopped) {
1036  availableSpace.push_back(seenSpace);
1037  hadVehicles.push_back(hadVehicle);
1038  continue;
1039  }
1040  // get the next lane, determine whether it is an internal lane
1041  MSLane* approachedLane = item.myLink->getViaLane();
1042  if (approachedLane != 0) {
1043  if (item.myLink->isCrossing()/* && item.myLink->willHaveBlockedFoe()*/) {
1044  seenSpace = seenSpace - approachedLane->getVehLenSum();
1045  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1046  } else {
1047  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength();
1048  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1049  }
1050  availableSpace.push_back(seenSpace);
1051  hadVehicles.push_back(hadVehicle);
1052  continue;
1053  }
1054  approachedLane = item.myLink->getLane();
1055  MSVehicle* last = approachedLane->getLastVehicle();
1056  if (last == 0) {
1057  last = approachedLane->getPartialOccupator();
1058  if (last != 0) {
1059  SUMOReal m = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
1060  availableSpace.push_back(m);
1061  hadVehicle = true;
1062  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength();
1063  if (last->myHaveToWaitOnNextLink) {
1064  foundStopped = true;
1065  }
1066  } else {
1067 // seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
1068 // availableSpace.push_back(seenSpace);
1069  availableSpace.push_back(seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped));
1070  if (!foundStopped) {
1071  seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
1072  } else {
1073  seenSpace = availableSpace.back();
1074  }
1075  }
1076  } else {
1077  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
1078  SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
1079  SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
1080  SUMOReal m = MAX2(seenSpace, seenSpace + lastGap);
1081  availableSpace.push_back(m);
1082  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength();
1083  } else {
1084 // seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
1085 // availableSpace.push_back(seenSpace);
1086  availableSpace.push_back(seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped));
1087  if (!foundStopped) {
1088  seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
1089  } else {
1090  seenSpace = availableSpace.back();
1091  }
1092  }
1093  if (last->myHaveToWaitOnNextLink) {
1094  foundStopped = true;
1095  }
1096  hadVehicle = true;
1097  }
1098  hadVehicles.push_back(hadVehicle);
1099  }
1100 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1101  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1102  int bla = 0;
1103  }
1104 #endif
1105  for (int i = (int)(myLFLinkLanes.size() - 1); i > 0; --i) {
1106  DriveProcessItem& item = myLFLinkLanes[i - 1];
1107  const bool opened = item.myLink != 0 && (item.myLink->havePriority() ||
1108  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
1110  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !hadVehicles[i] || opened;
1111  if (!opened && item.myLink != 0) {
1112  if (i > 1) {
1113  DriveProcessItem& item2 = myLFLinkLanes[i - 2];
1114  if (item2.myLink != 0 && item2.myLink->isCont()) {
1115  allowsContinuation = true;
1116  }
1117  }
1118  }
1119  if (allowsContinuation) {
1120  availableSpace[i - 1] = availableSpace[i];
1121  }
1122  }
1123 
1124  for (unsigned int i = 0; hadVehicle && i < myLFLinkLanes.size() && removalBegin < 0; ++i) {
1125  // skip unset links
1126  DriveProcessItem& item = myLFLinkLanes[i];
1127  if (item.myLink == 0) {
1128  continue;
1129  }
1130  /*
1131  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1132  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1133  removalBegin = lastLinkToInternal;
1134  }
1135  */
1136 
1137  SUMOReal leftSpace = availableSpace[i] - getVehicleType().getLengthWithGap();
1138  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1139  SUMOReal impatienceCorrection = 0;
1140  /*
1141  if(item.myLink->getState()==LINKSTATE_MINOR) {
1142  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1143  }
1144  */
1145  if (leftSpace < -impatienceCorrection / 10.) {
1146  removalBegin = i;
1147  }
1148  //removalBegin = i;
1149  }
1150  }
1151  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1152  while (removalBegin < (int)(myLFLinkLanes.size())) {
1154  myLFLinkLanes[removalBegin].myVLinkPass = myLFLinkLanes[removalBegin].myVLinkWait;
1155  if (myLFLinkLanes[removalBegin].myDistance >= brakeGap || (myLFLinkLanes[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1156  myLFLinkLanes[removalBegin].mySetRequest = false;
1157  }
1158  ++removalBegin;
1159  }
1160  }
1161  }
1162 #else
1163  UNUSED_PARAMETER(lengthsInFront);
1164 #endif
1165  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1166  if ((*i).myLink != 0) {
1167  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).mySetRequest);
1168  }
1169  }
1170 }
1171 
1172 
1173 void
1175  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1176  if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) {
1177  ++rem;
1178  } else {
1179  if (rem->first->notifyEnter(*this, reason)) {
1180  ++rem;
1181  } else {
1182  rem = myMoveReminders.erase(rem);
1183  }
1184  }
1185  }
1186 }
1187 
1188 
1189 bool
1190 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1191  myAmOnNet = !onTeleporting;
1192  // vaporizing edge?
1193  /*
1194  if (enteredLane->getEdge().isVaporizing()) {
1195  // yep, let's do the vaporization...
1196  myLane = enteredLane;
1197  return true;
1198  }
1199  */
1200  // move mover reminder one lane further
1201  adaptLaneEntering2MoveReminder(*enteredLane);
1202  // set the entered lane as the current lane
1203  myLane = enteredLane;
1204 
1205  // internal edges are not a part of the route...
1206  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1207  assert(&enteredLane->getEdge() == *(myCurrEdge + 1));
1208  ++myCurrEdge;
1209  }
1210  if (!onTeleporting) {
1211  // may be optimized: compute only, if the current or the next have more than one lane...!!!
1212  getBestLanes(true);
1214 #ifndef NO_TRACI
1215  if (myInfluencer != 0) {
1217  }
1218 #endif
1219  } else {
1221  // normal move() isn't called so reset position here
1222  myState.myPos = 0;
1223  }
1224  return hasArrived();
1225 }
1226 
1227 
1228 void
1230  myAmOnNet = true;
1231 #ifdef _MESSAGES
1232  if (myLCMsgEmitter != 0) {
1234  myLCMsgEmitter->writeLaneChangeEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), enteredLane, getPosition().x(), getPosition().y());
1235  }
1236 #endif
1237  myLane = enteredLane;
1238  // switch to and activate the new lane's reminders
1239  // keep OldLaneReminders
1240  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1241  addReminder(*rem);
1242  }
1244  /*
1245  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1246  (*i)->resetPartialOccupation(this);
1247  }
1248  myFurtherLanes.clear();
1249  */
1250  if (myState.myPos - getVehicleType().getLength() < 0) {
1251  // we have to rebuild "further lanes"
1252  const MSRoute& route = getRoute();
1254  MSLane* lane = myLane;
1255  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1256  while (i != route.begin() && leftLength > 0) {
1257  /* const MSEdge* const prev = */ *(--i);
1258  lane = lane->getLogicalPredecessorLane();
1259  if (lane == 0) {
1260  break;
1261  }
1262  myFurtherLanes.push_back(lane);
1263  leftLength -= (lane)->setPartialOccupation(this, leftLength);
1264  /*
1265  const std::vector<MSLane::IncomingLaneInfo> &incomingLanes = lane->getIncomingLanes();
1266  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = incomingLanes.begin(); j != incomingLanes.end(); ++j) {
1267  if (&(*j).lane->getEdge() == prev) {
1268  #ifdef HAVE_INTERNAL_LANES
1269  (*j).lane->setPartialOccupation(this, leftLength);
1270  #else
1271  leftLength -= (*j).length;
1272  (*j).lane->setPartialOccupation(this, leftLength);
1273  #endif
1274  leftLength -= (*j).lane->getLength();
1275  break;
1276  }
1277  }
1278  */
1279  }
1280  }
1281 #ifndef NO_TRACI
1282  // check if further changes are necessary
1283  if (myInfluencer != 0) {
1285  }
1286 #endif
1287 }
1288 
1289 
1290 void
1292  myState = State(pos, speed);
1293  assert(myState.myPos >= 0);
1294  assert(myState.mySpeed >= 0);
1295  myWaitingTime = 0;
1296  myLane = enteredLane;
1297  // set and activate the new lane's reminders
1298  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1299  addReminder(*rem);
1300  }
1301  activateReminders(notification);
1302  std::string msg;
1303  if (MSGlobals::gCheckRoutes && !hasValidRoute(msg)) {
1304  throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
1305  }
1306  myAmOnNet = true;
1307  // build the list of lanes the vehicle is lapping into
1308  SUMOReal leftLength = myType->getLength() - pos;
1309  MSLane* clane = enteredLane;
1310  while (leftLength > 0) {
1311  clane = clane->getLogicalPredecessorLane();
1312  if (clane == 0) {
1313  break;
1314  }
1315  myFurtherLanes.push_back(clane);
1316  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1317  }
1318 }
1319 
1320 
1321 void
1323  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1324  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1325  ++rem;
1326  } else {
1327  rem = myMoveReminders.erase(rem);
1328  }
1329  }
1330  if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) {
1331  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1332  (*i)->resetPartialOccupation(this);
1333  }
1334  myFurtherLanes.clear();
1335  }
1336  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
1337  myAmOnNet = false;
1338  }
1339 }
1340 
1341 
1344  return *myLaneChangeModel;
1345 }
1346 
1347 
1350  return *myLaneChangeModel;
1351 }
1352 
1353 
1354 const std::vector<MSVehicle::LaneQ>&
1355 MSVehicle::getBestLanes(bool forceRebuild, MSLane* startLane) const {
1356 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1357  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1358  int bla = 0;
1359  myLastBestLanesEdge = 0;
1360  }
1361 #endif
1362 
1363  if (startLane == 0) {
1364  startLane = myLane;
1365  }
1366  // update occupancy and current lane index, only, if the vehicle has not moved to a new lane
1367  if (myLastBestLanesEdge == &startLane->getEdge() && !forceRebuild) {
1368  std::vector<LaneQ>& lanes = *myBestLanes.begin();
1369  std::vector<LaneQ>::iterator i;
1370  for (i = lanes.begin(); i != lanes.end(); ++i) {
1371  SUMOReal nextOccupation = 0;
1372  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1373  nextOccupation += (*j)->getVehLenSum();
1374  }
1375  (*i).nextOccupation = nextOccupation;
1376  if ((*i).lane == startLane) {
1378  }
1379  }
1380  return *myBestLanes.begin();
1381  }
1382  // start rebuilding
1383  myLastBestLanesEdge = &startLane->getEdge();
1384  myBestLanes.clear();
1385 
1386  // get information about the next stop
1387  const MSEdge* nextStopEdge = 0;
1388  const MSLane* nextStopLane = 0;
1389  SUMOReal nextStopPos = 0;
1390  if (!myStops.empty()) {
1391  const Stop& nextStop = myStops.front();
1392  nextStopLane = nextStop.lane;
1393  nextStopEdge = &nextStopLane->getEdge();
1394  nextStopPos = nextStop.startPos;
1395  }
1396  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
1397  nextStopEdge = *(myRoute->end() - 1);
1398  nextStopLane = nextStopEdge->getLanes()[myParameter->arrivalLane];
1399  nextStopPos = myArrivalPos;
1400  }
1401 
1402  // go forward along the next lanes;
1403  int seen = 0;
1404  SUMOReal seenLength = 0;
1405  bool progress = true;
1406  for (MSRouteIterator ce = myCurrEdge; progress;) {
1407  std::vector<LaneQ> currentLanes;
1408  const std::vector<MSLane*>* allowed = 0;
1409  const MSEdge* nextEdge = 0;
1410  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
1411  nextEdge = *(ce + 1);
1412  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
1413  }
1414  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
1415  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1416  LaneQ q;
1417  MSLane* cl = *i;
1418  q.lane = cl;
1419  q.bestContinuations.push_back(cl);
1420  q.bestLaneOffset = 0;
1421  q.length = cl->getLength();
1422  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
1423  currentLanes.push_back(q);
1424  }
1425  //
1426  if (nextStopEdge == *ce) {
1427  progress = false;
1428  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
1429  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
1430  (*q).allowsContinuation = false;
1431  (*q).length = nextStopPos;
1432  }
1433  }
1434  }
1435 
1436  myBestLanes.push_back(currentLanes);
1437  ++seen;
1438  seenLength += currentLanes[0].lane->getLength();
1439  ++ce;
1440  progress &= (seen <= 4 || seenLength < 3000);
1441  progress &= seen <= 8;
1442  progress &= ce != myRoute->end();
1443  /*
1444  if(progress) {
1445  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
1446  }
1447  */
1448  }
1449 
1450  // we are examining the last lane explicitly
1451  if (myBestLanes.size() != 0) {
1452  SUMOReal bestLength = -1;
1453  int bestThisIndex = 0;
1454  int index = 0;
1455  std::vector<LaneQ>& last = myBestLanes.back();
1456  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1457  if ((*j).length > bestLength) {
1458  bestLength = (*j).length;
1459  bestThisIndex = index;
1460  }
1461  }
1462  index = 0;
1463  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1464  if ((*j).length < bestLength) {
1465  (*j).bestLaneOffset = bestThisIndex - index;
1466  }
1467  }
1468  }
1469 
1470  // go backward through the lanes
1471  // track back best lane and compute the best prior lane(s)
1472  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
1473  std::vector<LaneQ>& nextLanes = (*(i - 1));
1474  std::vector<LaneQ>& clanes = (*i);
1475  MSEdge& cE = clanes[0].lane->getEdge();
1476  int index = 0;
1477  SUMOReal bestConnectedLength = -1;
1478  SUMOReal bestLength = -1;
1479  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
1480  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
1481  bestConnectedLength = (*j).length;
1482  }
1483  if (bestLength < (*j).length) {
1484  bestLength = (*j).length;
1485  }
1486  }
1487  if (bestConnectedLength > 0) {
1488  int bestThisIndex = 0;
1489  index = 0;
1490  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1491  LaneQ bestConnectedNext;
1492  bestConnectedNext.length = -1;
1493  if ((*j).allowsContinuation) {
1494  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
1495  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1496  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
1497  bestConnectedNext = *m;
1498  }
1499  }
1500  }
1501  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
1502  (*j).length += bestLength;
1503  } else {
1504  (*j).length += bestConnectedNext.length;
1505  }
1506  }
1507  if (clanes[bestThisIndex].length < (*j).length || (clanes[bestThisIndex].length == (*j).length && abs(abs(clanes[bestThisIndex].bestLaneOffset > (*j).bestLaneOffset)))) {
1508  bestThisIndex = index;
1509  }
1510  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
1511  }
1512 
1513  index = 0;
1514  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1515  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) < abs(clanes[bestThisIndex].bestLaneOffset))) {
1516  (*j).bestLaneOffset = bestThisIndex - index;
1517  } else {
1518  (*j).bestLaneOffset = 0;
1519  }
1520  }
1521 
1522  } else {
1523 
1524  int bestThisIndex = 0;
1525  int bestNextIndex = 0;
1526  int bestDistToNeeded = (int) clanes.size();
1527  index = 0;
1528  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1529  if ((*j).allowsContinuation) {
1530  int nextIndex = 0;
1531  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
1532  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1533  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
1534  bestDistToNeeded = abs((*m).bestLaneOffset);
1535  bestThisIndex = index;
1536  bestNextIndex = nextIndex;
1537  }
1538  }
1539  }
1540  }
1541  }
1542  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
1543  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
1544  index = 0;
1545  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1546  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) < abs(clanes[bestThisIndex].bestLaneOffset))) {
1547  (*j).bestLaneOffset = bestThisIndex - index;
1548  } else {
1549  (*j).bestLaneOffset = 0;
1550  }
1551  }
1552 
1553  }
1554 
1555  }
1556 
1557  // update occupancy and current lane index
1558  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
1559  std::vector<LaneQ>::iterator i;
1560  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
1561  SUMOReal nextOccupation = 0;
1562  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1563  nextOccupation += (*j)->getVehLenSum();
1564  }
1565  (*i).nextOccupation = nextOccupation;
1566  if ((*i).lane == startLane) {
1568  }
1569  }
1570  return *myBestLanes.begin();
1571 }
1572 
1573 
1574 const std::vector<MSLane*>&
1576  if (myBestLanes.empty() || myBestLanes[0].empty() || myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1577  return myEmptyLaneVector;
1578  }
1579  return (*myCurrentLaneInBestLanes).bestContinuations;
1580 }
1581 
1582 
1583 const std::vector<MSLane*>&
1585  if (myBestLanes.size() == 0) {
1586  return myEmptyLaneVector;
1587  }
1588  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
1589  if ((*i).lane == l) {
1590  return (*i).bestContinuations;
1591  }
1592  }
1593  return myEmptyLaneVector;
1594 }
1595 
1596 
1597 
1598 SUMOReal
1600 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1601  SUMOReal distance = 1000000.;
1602 #else
1604 #endif
1605  if (isOnRoad() && destEdge != NULL) {
1606  if (&myLane->getEdge() == *myCurrEdge) {
1607  // vehicle is on a normal edge
1608  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
1609  } else {
1610  // vehicle is on inner junction edge
1611  distance = myLane->getLength() - getPositionOnLane();
1612  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
1613  }
1614  }
1615  return distance;
1616 }
1617 
1618 
1619 SUMOReal
1622 }
1623 
1624 
1625 SUMOReal
1628 }
1629 
1630 
1631 SUMOReal
1634 }
1635 
1636 
1637 SUMOReal
1640 }
1641 
1642 
1643 SUMOReal
1646 }
1647 
1648 
1649 SUMOReal
1652 }
1653 
1654 
1655 SUMOReal
1658 }
1659 
1660 
1661 void
1663  if (myPersonDevice == 0) {
1665  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
1666  }
1667  myPersonDevice->addPerson(person);
1668  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
1669  myStops.front().duration = 0;
1670  }
1671 }
1672 
1673 
1674 unsigned int
1676  unsigned int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
1677  return boarded + myParameter->personNumber;
1678 }
1679 
1680 
1681 void
1684  int state = getLaneChangeModel().getOwnState();
1685  if ((state & LCA_LEFT) != 0) {
1687  } else if ((state & LCA_RIGHT) != 0) {
1689  } else {
1690  const MSLane* lane = getLane();
1691  MSLinkCont::const_iterator link = lane->succLinkSec(*this, 1, *lane, getBestLanesContinuation());
1692  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
1693  switch ((*link)->getDirection()) {
1694  case LINKDIR_TURN:
1695  case LINKDIR_LEFT:
1696  case LINKDIR_PARTLEFT:
1698  break;
1699  case LINKDIR_RIGHT:
1700  case LINKDIR_PARTRIGHT:
1702  break;
1703  default:
1704  break;
1705  }
1706  }
1707  }
1708 
1709 }
1710 
1711 
1712 void
1714  if (myType->amVehicleSpecific()) {
1715  delete myType;
1716  }
1717  myType = type;
1718 }
1719 
1720 unsigned int
1722  std::vector<MSLane*>::const_iterator laneP = std::find((*myCurrEdge)->getLanes().begin(), (*myCurrEdge)->getLanes().end(), myLane);
1723  return (unsigned int) std::distance((*myCurrEdge)->getLanes().begin(), laneP);
1724 }
1725 
1726 
1727 #ifndef NO_TRACI
1728 bool
1729 MSVehicle::addTraciStop(MSLane* lane, SUMOReal pos, SUMOReal /*radius*/, SUMOTime duration) {
1730  //if the stop exists update the duration
1731  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
1732  if (iter->lane == lane && fabs(iter->endPos - pos) < POSITION_EPS) {
1733  if (duration == 0 && !iter->reached) {
1734  myStops.erase(iter);
1735  } else {
1736  iter->duration = duration;
1737  }
1738  return true;
1739  }
1740  }
1741 
1743  newStop.lane = lane->getID();
1744  newStop.busstop = MSNet::getInstance()->getBusStopID(lane, pos);
1745  newStop.startPos = pos - POSITION_EPS;
1746  newStop.endPos = pos;
1747  newStop.duration = duration;
1748  newStop.until = -1;
1749  newStop.triggered = false;
1750  newStop.parking = false;
1751  newStop.index = STOP_INDEX_END;
1752  return addStop(newStop);
1753 }
1754 
1755 
1758  if (myInfluencer == 0) {
1759  myInfluencer = new Influencer();
1760  }
1761  return *myInfluencer;
1762 }
1763 
1764 
1765 SUMOReal
1767  if (myInfluencer != 0) {
1768  return myInfluencer->getOriginalSpeed();
1769  }
1770  return myState.mySpeed;
1771 }
1772 
1773 
1774 #endif
1775 
1776 
1777 /****************************************************************************/