SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-sim.org/
15 // Copyright (C) 2002-2014 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 //#define DEBUG_VEHICLE_GUI_SELECTION 1
53 #ifdef DEBUG_VEHICLE_GUI_SELECTION
55 #include <guisim/GUIVehicle.h>
56 #include <guisim/GUILane.h>
57 #endif
58 
59 
60 // ===========================================================================
61 // member method definitions
62 // ===========================================================================
63 MSLaneChanger::MSLaneChanger(std::vector<MSLane*>* lanes, bool allowSwap)
64  : myAllowsSwap(allowSwap) {
65  assert(lanes->size() > 1);
66 
67  // Fill the changer with the lane-data.
68  myChanger.reserve(lanes->size());
69  for (std::vector<MSLane*>::iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
70  ChangeElem ce;
71  ce.follow = 0;
72  ce.lead = 0;
73  ce.lane = *lane;
74  ce.veh = (*lane)->myVehicles.rbegin();
75  ce.hoppedVeh = 0;
76  ce.lastBlocked = 0;
77  ce.firstBlocked = 0;
78  myChanger.push_back(ce);
79  }
80 }
81 
82 
84 
85 
86 void
88  // This is what happens in one timestep. After initialization of the
89  // changer, each vehicle will try to change. After that the changer
90  // nedds an update to prevent multiple changes of one vehicle.
91  // Finally, the change-result has to be given back to the lanes.
92  initChanger();
93  while (vehInChanger()) {
94 
95  bool haveChanged = change();
96  updateChanger(haveChanged);
97  }
98  updateLanes(t);
99 }
100 
101 
102 void
104  // Prepare myChanger with a safe state.
105  for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
106  ce->lead = 0;
107  ce->hoppedVeh = 0;
108  ce->lastBlocked = 0;
109  ce->firstBlocked = 0;
110  ce->dens = 0;
111 
112  MSLane::VehCont& vehicles = ce->lane->myVehicles;
113  if (vehicles.empty()) {
114  ce->veh = vehicles.rend();
115  ce->follow = 0;
116  continue;
117  }
118  ce->veh = vehicles.rbegin();
119  if (vehicles.size() == 1) {
120  ce->follow = 0;
121  continue;
122  }
123  ce->follow = *(vehicles.rbegin() + 1);
124  }
125 }
126 
127 
128 bool
130  // Find change-candidate. If it is on an allowed lane, try to change
131  // to the right (there is a rule in Germany that you have to change
132  // to the right, unless you are overtaking). If change to the right
133  // isn't possible, check if there is a possibility to overtake (on the
134  // left.
135  // If candidate isn't on an allowed lane, changing to an allowed has
136  // priority.
138  MSVehicle* vehicle = veh(myCandi);
139 #ifdef DEBUG_VEHICLE_GUI_SELECTION
140  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(vehicle)->getGlID())) {
141  int bla = 0;
142  }
143 #endif
144  if (vehicle->getLane() != (*myCandi).lane || vehicle->getLaneChangeModel().isChangingLanes()) {
145  // vehicles shadows and changing vehicles are not eligible
146  registerUnchanged(vehicle);
147  return false;
148  }
149 #ifndef NO_TRACI
150  if (vehicle->hasInfluencer() && vehicle->getInfluencer().isVTDControlled()) {
151  return false; // !!! temporary; just because it broke, here
152  }
153 #endif
154  vehicle->updateBestLanes(); // needed?
155  for (int i = 0; i < (int) myChanger.size(); ++i) {
156  vehicle->adaptBestLanesOccupation(i, myChanger[i].dens);
157  }
158  const std::vector<MSVehicle::LaneQ>& preb = vehicle->getBestLanes();
159  std::pair<MSVehicle* const, SUMOReal> leader = getRealThisLeader(myCandi);
160  // check whether the vehicle wants and is able to change to right lane
161  int state1 = 0;
162  if (myCandi != myChanger.begin() && (myCandi - 1)->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
163  state1 = checkChange(-1, leader, preb);
164  bool changingAllowed1 = (state1 & LCA_BLOCKED) == 0;
165  // change if the vehicle wants to and is allowed to change
166  if ((state1 & LCA_RIGHT) != 0 && changingAllowed1) {
167  startChange(vehicle, myCandi, -1);
168  return true;
169  }
170  if ((state1 & LCA_RIGHT) != 0 && (state1 & LCA_URGENT) != 0) {
171  (myCandi - 1)->lastBlocked = vehicle;
172  if ((myCandi - 1)->firstBlocked == 0) {
173  (myCandi - 1)->firstBlocked = vehicle;
174  }
175  }
176  }
177 
178 
179 
180  // check whether the vehicle wants and is able to change to left lane
181  int state2 = 0;
182  if ((myCandi + 1) != myChanger.end() && (myCandi + 1)->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
183  state2 = checkChange(1, leader, preb);
184  bool changingAllowed2 = (state2 & LCA_BLOCKED) == 0;
185  // change if the vehicle wants to and is allowed to change
186  if ((state2 & LCA_LEFT) != 0 && changingAllowed2) {
187  startChange(vehicle, myCandi, 1);
188  return true;
189  }
190  if ((state2 & LCA_LEFT) != 0 && (state2 & LCA_URGENT) != 0) {
191  (myCandi + 1)->lastBlocked = vehicle;
192  if ((myCandi + 1)->firstBlocked == 0) {
193  (myCandi + 1)->firstBlocked = vehicle;
194  }
195  }
196  }
197 
198  if ((state1 & (LCA_URGENT)) != 0 && (state2 & (LCA_URGENT)) != 0) {
199  // ... wants to go to the left AND to the right
200  // just let them go to the right lane...
201  state2 = 0;
202  }
203  vehicle->getLaneChangeModel().setOwnState(state2 | state1);
204 
205  // check whether the vehicles should be swapped
206  if (myAllowsSwap && ((state1 & (LCA_URGENT)) != 0 || (state2 & (LCA_URGENT)) != 0)) {
207  // get the direction ...
208  ChangerIt target;
209  if ((state1 & (LCA_URGENT)) != 0) {
210  // ... wants to go right
211  target = myCandi - 1;
212  }
213  if ((state2 & (LCA_URGENT)) != 0) {
214  // ... wants to go left
215  target = myCandi + 1;
216  }
217  MSVehicle* prohibitor = target->lead;
218  if (target->hoppedVeh != 0) {
219  SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
220  if (prohibitor == 0 || (hoppedPos > vehicle->getPositionOnLane() && prohibitor->getPositionOnLane() > hoppedPos)) {
221  prohibitor = 0;// !!! vehicles should not jump over more than one lanetarget->hoppedVeh;
222  }
223  }
224  if (prohibitor != 0
225  &&
226  ((prohibitor->getLaneChangeModel().getOwnState() & (LCA_URGENT/*|LCA_SPEEDGAIN*/)) != 0
227  &&
228  (prohibitor->getLaneChangeModel().getOwnState() & (LCA_LEFT | LCA_RIGHT))
229  !=
230  (vehicle->getLaneChangeModel().getOwnState() & (LCA_LEFT | LCA_RIGHT))
231  )
232  ) {
233 
234  // check for position and speed
235  if (prohibitor->getVehicleType().getLengthWithGap() - vehicle->getVehicleType().getLengthWithGap() == 0) {
236  // ok, may be swapped
237  // remove vehicle to swap with
238  MSLane::VehCont::iterator i = find(target->lane->myTmpVehicles.begin(), target->lane->myTmpVehicles.end(), prohibitor);
239  if (i != target->lane->myTmpVehicles.end()) {
240  assert(*i == prohibitor);
241  target->lane->myTmpVehicles.erase(i);
242  // set this vehicle
243  target->hoppedVeh = vehicle;
244  target->lane->myTmpVehicles.insert(target->lane->myTmpVehicles.begin(), vehicle);
245  myCandi->hoppedVeh = prohibitor;
246  myCandi->lane->myTmpVehicles.insert(myCandi->lane->myTmpVehicles.begin(), prohibitor);
247 
248  // leave lane and detectors
251  // patch position and speed
252  SUMOReal p1 = vehicle->getPositionOnLane();
253  vehicle->myState.myPos = prohibitor->myState.myPos;
254  prohibitor->myState.myPos = p1;
255  p1 = vehicle->getSpeed();
256  vehicle->myState.mySpeed = prohibitor->myState.mySpeed;
257  prohibitor->myState.mySpeed = p1;
258  // enter lane and detectors
259  vehicle->enterLaneAtLaneChange(target->lane);
260  prohibitor->enterLaneAtLaneChange(myCandi->lane);
261  // mark lane change
262  vehicle->getLaneChangeModel().changed();
263  prohibitor->getLaneChangeModel().changed();
264  (myCandi)->dens += prohibitor->getVehicleType().getLengthWithGap();
265  (target)->dens += vehicle->getVehicleType().getLengthWithGap();
266  return true;
267  }
268  }
269  }
270  }
271  registerUnchanged(vehicle);
272  return false;
273 }
274 
275 
276 void
278  myCandi->lane->myTmpVehicles.insert(myCandi->lane->myTmpVehicles.begin(), veh(myCandi));
279  vehicle->getLaneChangeModel().unchanged();
280  (myCandi)->dens += vehicle->getVehicleType().getLengthWithGap();
281 }
282 
283 
284 void
285 MSLaneChanger::startChange(MSVehicle* vehicle, ChangerIt& from, int direction) {
286  ChangerIt to = from + direction;
287  to->hoppedVeh = vehicle;
288  // @todo delay entering the target lane until the vehicle intersects it
289  // physically (considering lane width and vehicle width)
290  to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
291  const bool continuous = vehicle->getLaneChangeModel().startLaneChangeManeuver(from->lane, to->lane, direction);
292  if (continuous) {
293  from->lane->myTmpVehicles.insert(from->lane->myTmpVehicles.begin(), vehicle);
294  from->dens += vehicle->getVehicleType().getLengthWithGap();
295  }
296  to->dens += to->hoppedVeh->getVehicleType().getLengthWithGap();
297 }
298 
299 
300 std::pair<MSVehicle* const, SUMOReal>
302  // get the leading vehicle on the lane to change to
303  MSVehicle* leader = target->lead;
304  if (leader == 0) {
305  MSLane* targetLane = target->lane;
306  MSVehicle* predP = targetLane->getPartialOccupator();
307  if (predP != 0) {
308  return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane());
309  }
310  const std::vector<MSLane*>& bestLaneConts = veh(myCandi)->getBestLanesContinuation();
311  MSLinkCont::const_iterator link = MSLane::succLinkSec(*veh(myCandi), 1, *targetLane, bestLaneConts);
312  if (targetLane->isLinkEnd(link)) {
313  return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1);
314  }
315  MSLane* nextLane = (*link)->getLane();
316  if (nextLane == 0) {
317  return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1);
318  }
319  leader = nextLane->getLastVehicle();
320  if (leader == 0) {
321  return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1);
322  }
323  SUMOReal gap =
324  leader->getPositionOnLane() - leader->getVehicleType().getLength()
325  +
326  (myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap()); // !!! recheck
327  return std::pair<MSVehicle* const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap));
328  } else {
329  MSVehicle* candi = veh(myCandi);
330  SUMOReal gap = leader->getPositionOnLane() - leader->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap();
331  return std::pair<MSVehicle* const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap));
332  }
333 }
334 
335 
336 std::pair<MSVehicle* const, SUMOReal>
338  // get the leading vehicle on the lane to change to
339  MSVehicle* neighLead = target->lead;
340  // check whether the hopped vehicle got the leader
341  if (target->hoppedVeh != 0) {
342  SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
343  if (hoppedPos > veh(myCandi)->getPositionOnLane() && (neighLead == 0 || neighLead->getPositionOnLane() > hoppedPos)) {
344  neighLead = target->hoppedVeh;
345  }
346  }
347  if (neighLead == 0) {
348  MSLane* targetLane = target->lane;
349  MSVehicle* predP = targetLane->getPartialOccupator();
350  if (predP != 0) {
351  return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap());
352  }
353  SUMOReal seen = myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane();
354  SUMOReal speed = veh(myCandi)->getSpeed();
356  if (seen > dist) {
357  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
358  }
359  const std::vector<MSLane*>& bestLaneConts = veh(myCandi)->getBestLanesContinuation(targetLane);
360  return target->lane->getLeaderOnConsecutive(dist, seen, speed, *veh(myCandi), bestLaneConts);
361  } else {
362  MSVehicle* candi = veh(myCandi);
363  return std::pair<MSVehicle* const, SUMOReal>(neighLead, neighLead->getPositionOnLane() - neighLead->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap());
364  }
365 }
366 
367 
368 std::pair<MSVehicle* const, SUMOReal>
370  MSVehicle* neighFollow = veh(target);
371  // check whether the hopped vehicle got the follower
372  if (target->hoppedVeh != 0) {
373  SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
374  if (hoppedPos <= veh(myCandi)->getPositionOnLane() && (neighFollow == 0 || neighFollow->getPositionOnLane() < hoppedPos)) {
375  neighFollow = target->hoppedVeh;
376  }
377  }
378  if (neighFollow == 0) {
379  SUMOReal speed = target->lane->getSpeedLimit();
380  // in order to look back, we'd need the minimum braking ability of vehicles in the net...
381  // we'll assume it to be 4m/s^2
382  // !!!revisit
383  SUMOReal dist = speed * speed / (2.*4.) + SPEED2DIST(speed);
384  dist = MIN2(dist, (SUMOReal) 500.);
385  MSVehicle* candi = veh(myCandi);
386  return target->lane->getFollowerOnConsecutive(dist, candi->getSpeed(), candi->getPositionOnLane() - candi->getVehicleType().getLength(), candi->getCarFollowModel().getMaxDecel());
387  } else {
388  MSVehicle* candi = veh(myCandi);
389  return std::pair<MSVehicle* const, SUMOReal>(neighFollow, candi->getPositionOnLane() - candi->getVehicleType().getLength() - neighFollow->getPositionOnLane() - neighFollow->getVehicleType().getMinGap());
390  }
391 }
392 
393 
394 
395 
396 void
397 MSLaneChanger::updateChanger(bool vehHasChanged) {
398  assert(myCandi->veh != myCandi->lane->myVehicles.rend());
399 
400  // "Push" the vehicles to the back, i.e. follower becomes vehicle,
401  // vehicle becomes leader, and leader becomes predecessor of vehicle,
402  // if it exists.
403  if (!vehHasChanged) {
404  myCandi->lead = veh(myCandi);
405  }
406  myCandi->veh = myCandi->veh + 1;
407 
408  if (veh(myCandi) == 0) {
409  assert(myCandi->follow == 0);
410  // leader already 0.
411  return;
412  }
413  if (myCandi->veh + 1 == myCandi->lane->myVehicles.rend()) {
414  myCandi->follow = 0;
415  } else {
416  myCandi->follow = *(myCandi->veh + 1);
417  }
418  return;
419 }
420 
421 
422 void
424 
425  // Update the lane's vehicle-container.
426  // First: it is bad style to change other classes members, but for
427  // this release, other attempts were too time-consuming. In a next
428  // release we will change from this lane-centered design to a vehicle-
429  // centered. This will solve many problems.
430  // Second: this swap would be faster if vehicle-containers would have
431  // been pointers, but then I had to change too much of the MSLane code.
432  for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
433 
434  ce->lane->swapAfterLaneChange(t);
435  }
436 }
437 
438 
441  // Find the vehicle in myChanger with the smallest position. If there
442  // is no vehicle in myChanger (shouldn't happen) , return
443  // myChanger.end().
444  ChangerIt max = myChanger.end();
445  for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
446  if (veh(ce) == 0) {
447  continue;
448  }
449  if (max == myChanger.end()) {
450  max = ce;
451  continue;
452  }
453  assert(veh(ce) != 0);
454  assert(veh(max) != 0);
455  if (veh(max)->getPositionOnLane() < veh(ce)->getPositionOnLane()) {
456  max = ce;
457  }
458  }
459  assert(max != myChanger.end());
460  assert(veh(max) != 0);
461  return max;
462 }
463 
464 int
466  int laneOffset,
467  const std::pair<MSVehicle* const, SUMOReal>& leader,
468  const std::vector<MSVehicle::LaneQ>& preb) const {
469  std::pair<MSVehicle* const, SUMOReal> neighLead = getRealLeader(myCandi + laneOffset);
470  std::pair<MSVehicle* const, SUMOReal> neighFollow = getRealFollower(myCandi + laneOffset);
471  MSVehicle* vehicle = veh(myCandi);
472  ChangerIt target = myCandi + laneOffset;
473  int blocked = 0;
474  int blockedByLeader = (laneOffset == -1 ? LCA_BLOCKED_BY_RIGHT_LEADER : LCA_BLOCKED_BY_LEFT_LEADER);
475  int blockedByFollower = (laneOffset == -1 ? LCA_BLOCKED_BY_RIGHT_FOLLOWER : LCA_BLOCKED_BY_LEFT_FOLLOWER);
476  // overlap
477  if (neighFollow.first != 0 && neighFollow.second < 0) {
478  blocked |= (blockedByFollower | LCA_OVERLAPPING);
479  }
480  if (neighLead.first != 0 && neighLead.second < 0) {
481  blocked |= (blockedByLeader | LCA_OVERLAPPING);
482  }
483  // safe back gap
484  if (neighFollow.first != 0) {
485  // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
486  if (neighFollow.second < neighFollow.first->getCarFollowModel().getSecureGap(neighFollow.first->getSpeed(), vehicle->getSpeed(), vehicle->getCarFollowModel().getMaxDecel())) {
487  blocked |= blockedByFollower;
488  }
489  }
490 
491  // safe front gap
492  if (neighLead.first != 0) {
493  // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
494  if (neighLead.second < vehicle->getCarFollowModel().getSecureGap(vehicle->getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())) {
495  blocked |= blockedByLeader;
496  }
497  }
498 
499  MSAbstractLaneChangeModel::MSLCMessager msg(leader.first, neighLead.first, neighFollow.first);
500  int state = blocked | vehicle->getLaneChangeModel().wantsChange(
501  laneOffset, msg, blocked, leader, neighLead, neighFollow, *(target->lane), preb, &(myCandi->lastBlocked), &(myCandi->firstBlocked));
502 
503 #ifndef NO_TRACI
504  // let TraCI influence the wish to change lanes and the security to take
505  //const int oldstate = state;
506  state = vehicle->influenceChangeDecision(state);
507  //if (vehicle->getID() == "150_2_36000000") {
508  // std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) << " veh=" << vehicle->getID() << " oldstate=" << oldstate << " newstate=" << state << "\n";
509  //}
510 #endif
511  return state;
512 }
513 
514 /****************************************************************************/
515 
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
MSVehicle * firstBlocked
the first vehicle on this edge that wants to change to this lane
Definition: MSLaneChanger.h:85
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:919
MSLane * lane
the lane the vehicle is on
Definition: MSLaneChanger.h:77
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:538
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1101
a vehicles
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:1043
SUMOReal getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
MSLane::VehCont::reverse_iterator veh
the regarded vehicle
Definition: MSLaneChanger.h:79
bool isVTDControlled() const
Definition: MSVehicle.h:981
void initChanger()
Initialize the changer before looping over all vehicles.
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
SUMOReal getLength() const
Get vehicle's length [m].
T MAX2(T a, T b)
Definition: StdDefs.h:72
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
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:232
SUMOReal mySpeed
the stored speed
Definition: MSVehicle.h:117
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's position along the lane.
Definition: MSVehicle.h:283
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:1626
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, unsigned int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:949
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:1750
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle's end.
Definition: MSLane.h:261
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's reaction time.
Definition: MSCFModel.h:213
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's current lane and their successors...
Definition: MSVehicle.cpp:2035
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:1768
The vehicle is blocked by left follower.
std::pair< MSVehicle *const, SUMOReal > getRealThisLeader(const ChangerIt &target) const
T MIN2(T a, T b)
Definition: StdDefs.h:66
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
Definition: MSCFModel.h:165
virtual void changed()=0
virtual MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:931
MSLaneChanger()
Default constructor.
int checkChange(int laneOffset, const std::pair< MSVehicle *const, SUMOReal > &leader, const std::vector< MSVehicle::LaneQ > &preb) const
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:1762
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:1710
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2328
bool myAllowsSwap
Whether blocking vehicles may be swapped.
~MSLaneChanger()
Destructor.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:95
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
Definition: MSLaneChanger.h:97
SUMOReal getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:291
SUMOReal myPos
the stored position
Definition: MSVehicle.h:110
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:253
void registerUnchanged(MSVehicle *vehicle)
#define SUMOReal
Definition: config.h:215
The vehicle is blocked by right follower.
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:2073
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:328
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:2346
bool vehInChanger() const
Check if there is a single change-candidate in the changer. Returns true if there is one...
GUISelectedStorage gSelected
A global holder of selected objects.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
The vehicle is blocked by right leader.
ChangerIt myCandi