SUMO - Simulation of Urban MObility
MSLaneChanger.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // Performs lane changing of vehicles
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
15 // Copyright (C) 2002-2016 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include "MSLaneChanger.h"
36 #include "MSNet.h"
37 #include "MSVehicle.h"
38 #include "MSVehicleType.h"
39 #include "MSVehicleTransfer.h"
40 #include "MSGlobals.h"
41 #include <cassert>
42 #include <iterator>
43 #include <cstdlib>
44 #include <cmath>
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 
53 // ===========================================================================
54 // member method definitions
55 // ===========================================================================
56 MSLaneChanger::MSLaneChanger(const std::vector<MSLane*>* lanes, bool allowSwap)
57  : myAllowsSwap(allowSwap) {
58  assert(lanes->size() > 1);
59 
60  // Fill the changer with the lane-data.
61  myChanger.reserve(lanes->size());
62  for (std::vector<MSLane*>::const_iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
63  ChangeElem ce;
64  ce.follow = 0;
65  ce.lead = 0;
66  ce.lane = *lane;
67  ce.veh = (*lane)->myVehicles.rbegin();
68  ce.hoppedVeh = 0;
69  ce.lastBlocked = 0;
70  ce.firstBlocked = 0;
71  myChanger.push_back(ce);
72  }
73 }
74 
75 
77 
78 
79 void
81  // This is what happens in one timestep. After initialization of the
82  // changer, each vehicle will try to change. After that the changer
83  // nedds an update to prevent multiple changes of one vehicle.
84  // Finally, the change-result has to be given back to the lanes.
85  initChanger();
86  while (vehInChanger()) {
87  bool haveChanged = change();
88  updateChanger(haveChanged);
89  }
90  updateLanes(t);
91 }
92 
93 
94 void
96  // Prepare myChanger with a safe state.
97  for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
98  ce->lead = 0;
99  ce->hoppedVeh = 0;
100  ce->lastBlocked = 0;
101  ce->firstBlocked = 0;
102  ce->dens = 0;
103 
104  MSLane::VehCont& vehicles = ce->lane->myVehicles;
105  if (vehicles.empty()) {
106  ce->veh = vehicles.rend();
107  ce->follow = 0;
108  continue;
109  }
110  ce->veh = vehicles.rbegin();
111  if (vehicles.size() == 1) {
112  ce->follow = 0;
113  continue;
114  }
115  ce->follow = *(vehicles.rbegin() + 1);
116  }
117 }
118 
119 
120 bool
122  // Find change-candidate. If it is on an allowed lane, try to change
123  // to the right (there is a rule in Germany that you have to change
124  // to the right, unless you are overtaking). If change to the right
125  // isn't possible, check if there is a possibility to overtake (on the
126  // left.
127  // If candidate isn't on an allowed lane, changing to an allowed has
128  // priority.
130  MSVehicle* vehicle = veh(myCandi);
131 #ifdef DEBUG_VEHICLE_GUI_SELECTION
132  if (gDebugSelectedVehicle == vehicle->getID()) {
133  int bla = 0;
134  }
135 #endif
136  if (vehicle->getLane() != (*myCandi).lane || vehicle->getLaneChangeModel().isChangingLanes()) {
137  // vehicles shadows and changing vehicles are not eligible
138  registerUnchanged(vehicle);
139  return false;
140  }
141 #ifndef NO_TRACI
142  if (vehicle->hasInfluencer() && vehicle->getInfluencer().isVTDControlled()) {
143  return false; // !!! temporary; just because it broke, here
144  }
145 #endif
146  vehicle->updateBestLanes(); // needed?
147  for (int i = 0; i < (int) myChanger.size(); ++i) {
148  vehicle->adaptBestLanesOccupation(i, myChanger[i].dens);
149  }
150  const std::vector<MSVehicle::LaneQ>& preb = vehicle->getBestLanes();
151  std::pair<MSVehicle* const, SUMOReal> leader = getRealLeader(myCandi);
152  // check whether the vehicle wants and is able to change to right lane
153  int state1 = 0;
154  if (myCandi != myChanger.begin() && (myCandi - 1)->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
155  state1 = checkChange(-1, leader, preb);
156  bool changingAllowed1 = (state1 & LCA_BLOCKED) == 0;
157  // change if the vehicle wants to and is allowed to change
158  if ((state1 & LCA_RIGHT) != 0 && changingAllowed1) {
159  startChange(vehicle, myCandi, -1);
160  return true;
161  }
162  if ((state1 & LCA_RIGHT) != 0 && (state1 & LCA_URGENT) != 0) {
163  (myCandi - 1)->lastBlocked = vehicle;
164  if ((myCandi - 1)->firstBlocked == 0) {
165  (myCandi - 1)->firstBlocked = vehicle;
166  }
167  }
168  }
169 
170 
171 
172  // check whether the vehicle wants and is able to change to left lane
173  int state2 = 0;
174  if ((myCandi + 1) != myChanger.end() && (myCandi + 1)->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
175  state2 = checkChange(1, leader, preb);
176  bool changingAllowed2 = (state2 & LCA_BLOCKED) == 0;
177  // change if the vehicle wants to and is allowed to change
178  if ((state2 & LCA_LEFT) != 0 && changingAllowed2) {
179  startChange(vehicle, myCandi, 1);
180  return true;
181  }
182  if ((state2 & LCA_LEFT) != 0 && (state2 & LCA_URGENT) != 0) {
183  (myCandi + 1)->lastBlocked = vehicle;
184  if ((myCandi + 1)->firstBlocked == 0) {
185  (myCandi + 1)->firstBlocked = vehicle;
186  }
187  }
188  }
189 
190  if ((state1 & (LCA_URGENT)) != 0 && (state2 & (LCA_URGENT)) != 0) {
191  // ... wants to go to the left AND to the right
192  // just let them go to the right lane...
193  state2 = 0;
194  }
195  vehicle->getLaneChangeModel().setOwnState(state2 | state1);
196 
197  // check whether the vehicles should be swapped
198  if (myAllowsSwap && ((state1 & (LCA_URGENT)) != 0 || (state2 & (LCA_URGENT)) != 0)) {
199  // get the direction ...
200  ChangerIt target;
201  int direction = 0;
202  if ((state1 & (LCA_URGENT)) != 0) {
203  // ... wants to go right
204  target = myCandi - 1;
205  direction = -1;
206  }
207  if ((state2 & (LCA_URGENT)) != 0) {
208  // ... wants to go left
209  target = myCandi + 1;
210  direction = 1;
211  }
212  MSVehicle* prohibitor = target->lead;
213  if (target->hoppedVeh != 0) {
214  SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
215  if (prohibitor == 0 || (hoppedPos > vehicle->getPositionOnLane() && prohibitor->getPositionOnLane() > hoppedPos)) {
216  prohibitor = 0;// !!! vehicles should not jump over more than one lanetarget->hoppedVeh;
217  }
218  }
219  if (prohibitor != 0
220  &&
221  ((prohibitor->getLaneChangeModel().getOwnState() & (LCA_URGENT/*|LCA_SPEEDGAIN*/)) != 0
222  &&
223  (prohibitor->getLaneChangeModel().getOwnState() & (LCA_LEFT | LCA_RIGHT))
224  !=
225  (vehicle->getLaneChangeModel().getOwnState() & (LCA_LEFT | LCA_RIGHT))
226  )
227  ) {
228 
229  // check for position and speed
230  if (prohibitor->getVehicleType().getLengthWithGap() - vehicle->getVehicleType().getLengthWithGap() == 0) {
231  // ok, may be swapped
232  // remove vehicle to swap with
233  MSLane::VehCont::iterator i = find(target->lane->myTmpVehicles.begin(), target->lane->myTmpVehicles.end(), prohibitor);
234  if (i != target->lane->myTmpVehicles.end()) {
235  assert(*i == prohibitor);
236  target->lane->myTmpVehicles.erase(i);
237  // set this vehicle
238  target->hoppedVeh = vehicle;
239  target->lane->myTmpVehicles.insert(target->lane->myTmpVehicles.begin(), vehicle);
240  myCandi->hoppedVeh = prohibitor;
241  myCandi->lane->myTmpVehicles.insert(myCandi->lane->myTmpVehicles.begin(), prohibitor);
242 
243  // leave lane and detectors
246  // patch position and speed
247  SUMOReal p1 = vehicle->getPositionOnLane();
248  vehicle->myState.myPos = prohibitor->myState.myPos;
249  prohibitor->myState.myPos = p1;
250  p1 = vehicle->getSpeed();
251  vehicle->myState.mySpeed = prohibitor->myState.mySpeed;
252  prohibitor->myState.mySpeed = p1;
253  // enter lane and detectors
254  vehicle->enterLaneAtLaneChange(target->lane);
255  prohibitor->enterLaneAtLaneChange(myCandi->lane);
256  // mark lane change
257  vehicle->getLaneChangeModel().changed(direction);
258  prohibitor->getLaneChangeModel().changed(-direction);
259  (myCandi)->dens += prohibitor->getVehicleType().getLengthWithGap();
260  (target)->dens += vehicle->getVehicleType().getLengthWithGap();
261  return true;
262  }
263  }
264  }
265  }
266  registerUnchanged(vehicle);
267  return false;
268 }
269 
270 
271 void
273  myCandi->lane->myTmpVehicles.insert(myCandi->lane->myTmpVehicles.begin(), veh(myCandi));
274  vehicle->getLaneChangeModel().unchanged();
275  (myCandi)->dens += vehicle->getVehicleType().getLengthWithGap();
276 }
277 
278 
279 void
280 MSLaneChanger::startChange(MSVehicle* vehicle, ChangerIt& from, int direction) {
281  ChangerIt to = from + direction;
282  to->hoppedVeh = vehicle;
283  // @todo delay entering the target lane until the vehicle intersects it
284  // physically (considering lane width and vehicle width)
285  to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
286  const bool continuous = vehicle->getLaneChangeModel().startLaneChangeManeuver(from->lane, to->lane, direction);
287  if (continuous) {
288  from->lane->myTmpVehicles.insert(from->lane->myTmpVehicles.begin(), vehicle);
289  from->dens += vehicle->getVehicleType().getLengthWithGap();
290  vehicle->myAngle = vehicle->computeAngle();
291  }
292  to->dens += to->hoppedVeh->getVehicleType().getLengthWithGap();
293 }
294 
295 
296 std::pair<MSVehicle* const, SUMOReal>
298  // get the leading vehicle on the lane to change to
299  MSVehicle* neighLead = target->lead;
300  // check whether the hopped vehicle became the leader
301  if (target->hoppedVeh != 0) {
302  SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
303  if (hoppedPos > veh(myCandi)->getPositionOnLane() && (neighLead == 0 || neighLead->getPositionOnLane() > hoppedPos)) {
304  neighLead = target->hoppedVeh;
305  }
306  }
307  if (neighLead == 0) {
308  MSLane* targetLane = target->lane;
309  MSVehicle* predP = targetLane->getPartialOccupator();
310  if (predP != 0) {
311  return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap());
312  }
313  SUMOReal seen = myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane();
314  SUMOReal speed = veh(myCandi)->getSpeed();
316  if (seen > dist) {
317  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
318  }
319  const std::vector<MSLane*>& bestLaneConts = veh(myCandi)->getBestLanesContinuation(targetLane);
320  return target->lane->getLeaderOnConsecutive(dist, seen, speed, *veh(myCandi), bestLaneConts);
321  } else {
322  MSVehicle* candi = veh(myCandi);
323  return std::pair<MSVehicle* const, SUMOReal>(neighLead, neighLead->getPositionOnLane() - neighLead->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap());
324  }
325 }
326 
327 
328 std::pair<MSVehicle* const, SUMOReal>
330  MSVehicle* neighFollow = veh(target);
331  // check whether the hopped vehicle became the follower
332  if (target->hoppedVeh != 0) {
333  SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
334  if (hoppedPos <= veh(myCandi)->getPositionOnLane() && (neighFollow == 0 || neighFollow->getPositionOnLane() < hoppedPos)) {
335  neighFollow = target->hoppedVeh;
336  }
337  }
338  if (neighFollow == 0) {
339  MSVehicle* candi = veh(myCandi);
340  return target->lane->getFollowerOnConsecutive(
341  candi->getPositionOnLane() - candi->getVehicleType().getLength(),
342  candi->getSpeed(), candi->getCarFollowModel().getMaxDecel());
343  } else {
344  MSVehicle* candi = veh(myCandi);
345  return std::pair<MSVehicle* const, SUMOReal>(neighFollow,
346  candi->getPositionOnLane() - candi->getVehicleType().getLength() - neighFollow->getPositionOnLane() - neighFollow->getVehicleType().getMinGap());
347  }
348 }
349 
350 
351 
352 
353 void
354 MSLaneChanger::updateChanger(bool vehHasChanged) {
355  assert(myCandi->veh != myCandi->lane->myVehicles.rend());
356 
357  // "Push" the vehicles to the back, i.e. follower becomes vehicle,
358  // vehicle becomes leader, and leader becomes predecessor of vehicle,
359  // if it exists.
360  if (!vehHasChanged || MSGlobals::gLaneChangeDuration > DELTA_T) {
361  myCandi->lead = veh(myCandi);
362  }
363  myCandi->veh = myCandi->veh + 1;
364 
365  if (veh(myCandi) == 0) {
366  assert(myCandi->follow == 0);
367  // leader already 0.
368  return;
369  }
370  if (myCandi->veh + 1 == myCandi->lane->myVehicles.rend()) {
371  myCandi->follow = 0;
372  } else {
373  myCandi->follow = *(myCandi->veh + 1);
374  }
375  return;
376 }
377 
378 
379 void
381 
382  // Update the lane's vehicle-container.
383  // First: it is bad style to change other classes members, but for
384  // this release, other attempts were too time-consuming. In a next
385  // release we will change from this lane-centered design to a vehicle-
386  // centered. This will solve many problems.
387  // Second: this swap would be faster if vehicle-containers would have
388  // been pointers, but then I had to change too much of the MSLane code.
389  for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
390 
391  ce->lane->swapAfterLaneChange(t);
392  }
393 }
394 
395 
398  // Find the vehicle in myChanger with the smallest position. If there
399  // is no vehicle in myChanger (shouldn't happen) , return
400  // myChanger.end().
401  ChangerIt max = myChanger.end();
402  for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
403  if (veh(ce) == 0) {
404  continue;
405  }
406  if (max == myChanger.end()) {
407  max = ce;
408  continue;
409  }
410  assert(veh(ce) != 0);
411  assert(veh(max) != 0);
412  if (veh(max)->getPositionOnLane() < veh(ce)->getPositionOnLane()) {
413  max = ce;
414  }
415  }
416  assert(max != myChanger.end());
417  assert(veh(max) != 0);
418  return max;
419 }
420 
421 int
423  int laneOffset,
424  const std::pair<MSVehicle* const, SUMOReal>& leader,
425  const std::vector<MSVehicle::LaneQ>& preb) const {
426  std::pair<MSVehicle* const, SUMOReal> neighLead = getRealLeader(myCandi + laneOffset);
427  std::pair<MSVehicle* const, SUMOReal> neighFollow = getRealFollower(myCandi + laneOffset);
428  MSVehicle* vehicle = veh(myCandi);
429  ChangerIt target = myCandi + laneOffset;
430  int blocked = 0;
431  int blockedByLeader = (laneOffset == -1 ? LCA_BLOCKED_BY_RIGHT_LEADER : LCA_BLOCKED_BY_LEFT_LEADER);
432  int blockedByFollower = (laneOffset == -1 ? LCA_BLOCKED_BY_RIGHT_FOLLOWER : LCA_BLOCKED_BY_LEFT_FOLLOWER);
433  // overlap
434  if (neighFollow.first != 0 && neighFollow.second < 0) {
435  blocked |= (blockedByFollower | LCA_OVERLAPPING);
436  }
437  if (neighLead.first != 0 && neighLead.second < 0) {
438  blocked |= (blockedByLeader | LCA_OVERLAPPING);
439  }
440  // safe back gap
441  if (neighFollow.first != 0) {
442  // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
443  if (neighFollow.second < neighFollow.first->getCarFollowModel().getSecureGap(neighFollow.first->getSpeed(), vehicle->getSpeed(), vehicle->getCarFollowModel().getMaxDecel())) {
444  blocked |= blockedByFollower;
445  }
446  }
447 
448  // safe front gap
449  if (neighLead.first != 0) {
450  // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
451  if (neighLead.second < vehicle->getCarFollowModel().getSecureGap(vehicle->getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())) {
452  blocked |= blockedByLeader;
453  }
454  }
455 
456  MSAbstractLaneChangeModel::MSLCMessager msg(leader.first, neighLead.first, neighFollow.first);
457  int state = blocked | vehicle->getLaneChangeModel().wantsChange(
458  laneOffset, msg, blocked, leader, neighLead, neighFollow, *(target->lane), preb, &(myCandi->lastBlocked), &(myCandi->firstBlocked));
459 
460  if (blocked == 0 && (state & LCA_WANTS_LANECHANGE) != 0 && neighLead.first != 0) {
461  // do are more carefull (but expensive) check to ensure that a
462  // safety-critical leader is not being overloocked
463  const SUMOReal seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
464  const SUMOReal speed = vehicle->getSpeed();
465  const SUMOReal dist = vehicle->getCarFollowModel().brakeGap(speed) + vehicle->getVehicleType().getMinGap();
466  const MSLane* targetLane = (myCandi + laneOffset)->lane;
467  if (seen < dist) {
468  std::pair<MSVehicle* const, SUMOReal> neighLead2 = targetLane->getCriticalLeader(dist, seen, speed, *vehicle);
469  if (neighLead2.first != 0 && neighLead2.first != neighLead.first
470  && (neighLead2.second < vehicle->getCarFollowModel().getSecureGap(
471  vehicle->getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
472  state |= blockedByLeader;
473  }
474  }
475  }
476  if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
477  // ensure that merging is safe for any upcoming zipper links after changing
478  if (vehicle->unsafeLinkAhead((myCandi + laneOffset)->lane)) {
479  state |= blockedByLeader;
480  }
481  }
482 
483  if ((state & LCA_BLOCKED) == 0 && (state & LCA_WANTS_LANECHANGE) != 0 && MSGlobals::gLaneChangeDuration > DELTA_T) {
484  // ensure that a continuous lane change manoeuvre can be completed
485  // before the next turning movement
486  SUMOReal seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
488  const SUMOReal avgSpeed = 0.5 * (vehicle->getSpeed() + MAX2((SUMOReal)0, vehicle->getSpeed() - decel));
489  const SUMOReal space2change = avgSpeed * STEPS2TIME(MSGlobals::gLaneChangeDuration);
490  // for finding turns it doesn't matter whether we look along the current lane or the target lane
491  const std::vector<MSLane*>& bestLaneConts = vehicle->getBestLanesContinuation();
492  unsigned int view = 1;
493  MSLane* nextLane = vehicle->getLane();
494  MSLinkCont::const_iterator link = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
495  while (!nextLane->isLinkEnd(link) && seen <= space2change) {
496  if ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT
497  // the lanes after an internal junction are on different
498  // edges and do not allow lane-changing
499  || (nextLane->getEdge().isInternal() && (*link)->getViaLaneOrLane()->getEdge().isInternal())
500  ) {
501  state |= LCA_INSUFFICIENT_SPACE;
502  break;
503  }
504 #ifdef HAVE_INTERNAL_LANES
505  if ((*link)->getViaLane() == 0) {
506  view++;
507  }
508 #else
509  view++;
510 #endif
511  nextLane = (*link)->getViaLaneOrLane();
512  seen += nextLane->getLength();
513  // get the next link used
514  link = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
515  }
516 
517  if ((state & LCA_BLOCKED) == 0) {
518  // check for dangerous leaders in case the target lane changes laterally between
519  // now and the lane-changing midpoint
520  const SUMOReal speed = vehicle->getSpeed();
521  seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
522  nextLane = vehicle->getLane();
523  view = 1;
524  const SUMOReal dist = vehicle->getCarFollowModel().brakeGap(speed) + vehicle->getVehicleType().getMinGap();
525  MSLinkCont::const_iterator link = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
526  while (!nextLane->isLinkEnd(link) && seen <= space2change && seen <= dist) {
527  nextLane = (*link)->getViaLaneOrLane();
528  MSLane* targetLane = nextLane->getParallelLane(laneOffset);
529  if (targetLane == 0) {
530  state |= LCA_INSUFFICIENT_SPACE;
531  break;
532  } else {
533  std::pair<MSVehicle* const, SUMOReal> neighLead2 = targetLane->getLeader(vehicle, -seen, true);
534  if (neighLead2.first != 0 && neighLead2.first != neighLead.first
535  && (neighLead2.second < vehicle->getCarFollowModel().getSecureGap(
536  vehicle->getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
537  state |= blockedByLeader;
538  break;
539  }
540  }
541 #ifdef HAVE_INTERNAL_LANES
542  if ((*link)->getViaLane() == 0) {
543  view++;
544  }
545 #else
546  view++;
547 #endif
548  seen += nextLane->getLength();
549  // get the next link used
550  link = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
551  }
552  }
553  }
554 #ifndef NO_TRACI
555  // let TraCI influence the wish to change lanes and the security to take
556  //const int oldstate = state;
557  state = vehicle->influenceChangeDecision(state);
558  //if (vehicle->getID() == "150_2_36000000") {
559  // std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) << " veh=" << vehicle->getID() << " oldstate=" << oldstate << " newstate=" << state << "\n";
560  //}
561 #endif
562  return state;
563 }
564 
565 /****************************************************************************/
566 
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge&#39;e lanes.
MSVehicle * firstBlocked
the first vehicle on this edge that wants to change to this lane
Definition: MSLaneChanger.h:85
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:467
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:864
long long int SUMOTime
Definition: SUMOTime.h:43
MSLane * lane
the lane the vehicle is on
Definition: MSLaneChanger.h:77
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:627
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1273
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
std::pair< MSVehicle *const, SUMOReal > getRealLeader(const ChangerIt &target) const
bool hasInfluencer() const
Definition: MSVehicle.h:1200
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
MSLane::VehCont::reverse_iterator veh
the regarded vehicle
Definition: MSLaneChanger.h:79
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
Definition: MSVehicle.cpp:2646
bool isVTDControlled() const
Definition: MSVehicle.cpp:427
void initChanger()
Initialize the changer before looping over all vehicles.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:375
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
SUMOReal getLength() const
Get vehicle&#39;s length [m].
T MAX2(T a, T b)
Definition: StdDefs.h:75
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
MSVehicle * veh(ConstChangerIt ce) const
SUMOReal getSecureGap(const SUMOReal speed, const SUMOReal leaderSpeed, const SUMOReal leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum.
Definition: MSCFModel.h:272
SUMOReal mySpeed
the stored speed
Definition: MSVehicle.h:120
void startChange(MSVehicle *vehicle, ChangerIt &from, int direction)
start the lane change maneuver (and finish it instantly if gLaneChangeDuration == 0) ...
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:340
std::pair< MSVehicle *const, SUMOReal > getCriticalLeader(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh) const
Returns the most dangerous leader and the distance to him.
Definition: MSLane.cpp:1229
MSVehicle * lead
the vehicle in front of the current vehicle
Definition: MSLaneChanger.h:75
The action is urgent (to be defined by lc-model)
MSVehicle * follow
the vehicle following the current vehicle
Definition: MSLaneChanger.h:73
ChangerIt findCandidate()
Find current candidate. If there is none, myChanger.end() is returned.
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:1914
The link is a (hard) left direction.
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, unsigned int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:898
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2025
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:93
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle&#39;s end.
Definition: MSLane.h:260
A class responsible for exchanging messages between cars involved in lane-change interaction.
The vehicle changes lanes (micro only)
Wants go to the left.
#define max(a, b)
Definition: polyfonts.c:65
std::pair< MSVehicle *const, SUMOReal > getRealFollower(const ChangerIt &target) const
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time.
Definition: MSCFModel.h:234
SUMOReal computeAngle() const
compute the current vehicle angle
Definition: MSVehicle.cpp:769
void updateChanger(bool vehHasChanged)
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle&#39;s current lane and their successors...
Definition: MSVehicle.cpp:2340
SUMOReal myAngle
the angle (
Definition: MSVehicle.h:1318
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:2043
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:991
The vehicle is blocked by left follower.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
The link is a (hard) right direction.
std::pair< MSVehicle *const, SUMOReal > getLeader(const MSVehicle *veh, const SUMOReal vehPos, bool checkNext) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:1135
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:186
MSLaneChanger()
Default constructor.
int checkChange(int laneOffset, const std::pair< MSVehicle *const, SUMOReal > &leader, const std::vector< MSVehicle::LaneQ > &preb) const
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:247
void updateLanes(SUMOTime t)
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2037
Wants go to the right.
MSVehicle * lastBlocked
the vehicle that really wants to change to this lane
Definition: MSLaneChanger.h:83
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
void leaveLane(const MSMoveReminder::Notification reason)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:1982
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2826
bool myAllowsSwap
Whether blocking vehicles may be swapped.
~MSLaneChanger()
Destructor.
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:93
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
Definition: MSLaneChanger.h:97
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:348
virtual void changed(int dir)=0
SUMOReal myPos
the stored position
Definition: MSVehicle.h:113
Changer myChanger
Container for ChangeElemements, one for every lane in the edge.
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Definition: MSLane.h:252
void registerUnchanged(MSVehicle *vehicle)
#define SUMOReal
Definition: config.h:213
The vehicle is blocked by right follower.
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:2378
virtual int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, SUMOReal > &leader, const std::pair< MSVehicle *, SUMOReal > &neighLead, const std::pair< MSVehicle *, SUMOReal > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)=0
Called to examine whether the vehicle wants to change using the given laneOffset. This method gets th...
The vehicle is blocked by left leader.
MSVehicle * hoppedVeh
last vehicle that changed into this lane
Definition: MSLaneChanger.h:81
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:385
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:2844
bool vehInChanger() const
Check if there is a single change-candidate in the changer. Returns true if there is one...
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:81
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
The vehicle is blocked by right leader.
ChangerIt myCandi
const std::string & getID() const
Returns the name of the vehicle.