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 "MSNet.h"
36 #include "MSEdge.h"
37 #include "MSLane.h"
38 #include "MSGlobals.h"
39 
40 /* -------------------------------------------------------------------------
41  * MSAbstractLaneChangeModel-methods
42  * ----------------------------------------------------------------------- */
43 
45  myVehicle(v),
46  myOwnState(0),
47  myLastLaneChangeOffset(0),
48  myLaneChangeCompletion(1.0),
49  myLaneChangeDirection(0),
50  myLaneChangeMidpointPassed(false),
51  myAlreadyMoved(false),
52  myShadowLane(0),
53  myHaveShadow(false),
54 #ifndef NO_TRACI
55  myChangeRequest(MSVehicle::REQUEST_NONE),
56 #endif
57  myCarFollowModel(v.getCarFollowModel()) {
58 }
59 
60 
63 }
64 
65 
66 bool
68  if (neighLeader == 0) {
69  return false;
70  }
71  // Congested situation are relevant only on highways (maxSpeed > 70km/h)
72  // and congested on German Highways means that the vehicles have speeds
73  // below 60km/h. Overtaking on the right is allowed then.
74  if ((myVehicle.getLane()->getSpeedLimit() <= 70.0 / 3.6) || (neighLeader->getLane()->getSpeedLimit() <= 70.0 / 3.6)) {
75 
76  return false;
77  }
78  if (myVehicle.congested() && neighLeader->congested()) {
79  return true;
80  }
81  return false;
82 }
83 
84 
85 bool
87  if (leader == 0) {
88  return false;
89  }
90  // let's check it on highways only
91  if (leader->getSpeed() < (80.0 / 3.6)) {
92  return false;
93  }
95  return gap < myCarFollowModel.interactionGap(&myVehicle, leader->getSpeed());
96 }
97 
98 
99 bool
101  target->enteredByLaneChange(&myVehicle);
104  myShadowLane = target;
105  myHaveShadow = true;
107  myLaneChangeDirection = direction;
109  return true;
110  } else {
112  source->leftByLaneChange(&myVehicle);
115  changed();
116  return false;
117  }
118 }
119 
120 
121 void
123  if (moved && myHaveShadow) {
124  // move shadow to next lane
127  myShadowLane = myVehicle.getLane()->getParallelLane(shadowDirection);
128  if (myShadowLane == 0) {
129  // abort lane change
130  WRITE_WARNING("Vehicle '" + myVehicle.getID() + "' could not finish continuous lane change (lane disappeared) time=" +
131  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
133  return;
134  }
135  myHaveShadow = true;
136  }
140  // maneuver midpoint reached, swap myLane and myShadowLane
142  MSLane* tmp = myVehicle.getLane();
145  myShadowLane = tmp;
147  // internal lanes do not appear in bestLanes so we need to update
148  // myCurrentLaneInBestLanes explicitly
150  if (myVehicle.fixContinuations()) {
151  WRITE_WARNING("vehicle '" + myVehicle.getID() + "' could not reconstruct bestLanes when changing lanes on lane '" + myVehicle.getLane()->getID() + " time="
152  + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
153  }
154  }
155  if (myVehicle.fixPosition()) {
156  WRITE_WARNING("vehicle '" + myVehicle.getID() + "' set back by " + toString(myVehicle.getPositionOnLane() - myVehicle.getLane()->getLength()) +
157  "m when changing lanes on lane '" + myVehicle.getLane()->getID() + " time=" +
158  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
159  }
161  changed();
162  myAlreadyMoved = true;
163  }
164  // remove shadow as soon as the vehicle leaves the original lane geometrically
166  const SUMOReal sourceHalfWidth = myShadowLane->getWidth() / 2.0;
167  const SUMOReal targetHalfWidth = myVehicle.getLane()->getWidth() / 2.0;
168  if (myLaneChangeCompletion * (sourceHalfWidth + targetHalfWidth) - myVehicle.getVehicleType().getWidth() / 2.0 > sourceHalfWidth) {
170  }
171  }
172  // finish maneuver
173  if (!isChangingLanes()) {
176  }
177 }
178 
179 
180 void
182  if (myShadowLane != 0 && myHaveShadow) {
184  myHaveShadow = false;
185  }
186 }