SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSAbstractLaneChangeModel.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // Interface for lane-change models
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
14 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
35 #include "MSLCM_DK2008.h"
36 #include "MSLCM_LC2013.h"
37 #include "MSLCM_JE2013.h"
38 #include "MSNet.h"
39 #include "MSEdge.h"
40 #include "MSLane.h"
41 #include "MSGlobals.h"
42 
43 /* -------------------------------------------------------------------------
44  * MSAbstractLaneChangeModel-methods
45  * ----------------------------------------------------------------------- */
46 
49  switch (lcm) {
50  case LCM_DK2008:
51  return new MSLCM_DK2008(v);
52  case LCM_LC2013:
53  return new MSLCM_LC2013(v);
54  case LCM_JE2013:
55  return new MSLCM_JE2013(v);
56  default:
57  throw ProcessError("Lane change model '" + toString(lcm) + "' not implemented");
58  }
59 }
60 
61 
63  myVehicle(v),
64  myOwnState(0),
65  myLastLaneChangeOffset(0),
66  myLaneChangeCompletion(1.0),
67  myLaneChangeDirection(0),
68  myLaneChangeMidpointPassed(false),
69  myAlreadyMoved(false),
70  myShadowLane(0),
71  myHaveShadow(false),
72  myCarFollowModel(v.getCarFollowModel()) {
73 }
74 
75 
78 }
79 
80 
81 bool
83  if (neighLeader == 0) {
84  return false;
85  }
86  // Congested situation are relevant only on highways (maxSpeed > 70km/h)
87  // and congested on German Highways means that the vehicles have speeds
88  // below 60km/h. Overtaking on the right is allowed then.
89  if ((myVehicle.getLane()->getSpeedLimit() <= 70.0 / 3.6) || (neighLeader->getLane()->getSpeedLimit() <= 70.0 / 3.6)) {
90 
91  return false;
92  }
93  if (myVehicle.congested() && neighLeader->congested()) {
94  return true;
95  }
96  return false;
97 }
98 
99 
100 bool
102  if (leader == 0) {
103  return false;
104  }
105  // let's check it on highways only
106  if (leader->getSpeed() < (80.0 / 3.6)) {
107  return false;
108  }
110  return gap < myCarFollowModel.interactionGap(&myVehicle, leader->getSpeed());
111 }
112 
113 
114 bool
116  target->enteredByLaneChange(&myVehicle);
119  myShadowLane = target;
120  myHaveShadow = true;
122  myLaneChangeDirection = direction;
124  return true;
125  } else {
127  source->leftByLaneChange(&myVehicle);
130  changed();
131  return false;
132  }
133 }
134 
135 
136 void
138  if (moved && myHaveShadow) {
139  // move shadow to next lane
142  myShadowLane = myVehicle.getLane()->getParallelLane(shadowDirection);
143  if (myShadowLane == 0) {
144  // abort lane change
145  WRITE_WARNING("Vehicle '" + myVehicle.getID() + "' could not finish continuous lane change (lane disappeared) time=" +
146  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
148  return;
149  }
150  myHaveShadow = true;
151  }
155  // maneuver midpoint reached, swap myLane and myShadowLane
157  MSLane* tmp = myVehicle.getLane();
160  myShadowLane = tmp;
161  if (myVehicle.fixPosition()) {
162  WRITE_WARNING("vehicle '" + myVehicle.getID() + "' set back by " + toString(myVehicle.getPositionOnLane() - myVehicle.getLane()->getLength()) +
163  "m when changing lanes on lane '" + myVehicle.getLane()->getID() + " time=" +
164  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
165  }
167  changed();
168  myAlreadyMoved = true;
169  }
170  // remove shadow as soon as the vehicle leaves the original lane geometrically
172  const SUMOReal sourceHalfWidth = myShadowLane->getWidth() / 2.0;
173  const SUMOReal targetHalfWidth = myVehicle.getLane()->getWidth() / 2.0;
174  if (myLaneChangeCompletion * (sourceHalfWidth + targetHalfWidth) - myVehicle.getVehicleType().getWidth() / 2.0 > sourceHalfWidth) {
176  }
177  }
178  // finish maneuver
179  if (!isChangingLanes()) {
182  }
183 }
184 
185 
186 void
188  if (myShadowLane != 0 && myHaveShadow) {
190  myHaveShadow = false;
191  }
192 }