SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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.dlr.de/
14 // Copyright (C) 2001-2016 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 
36 #include <microsim/MSNet.h>
37 #include <microsim/MSEdge.h>
38 #include <microsim/MSLane.h>
39 #include <microsim/MSGlobals.h>
40 #include "MSLCM_DK2008.h"
41 #include "MSLCM_LC2013.h"
42 #include "MSLCM_SL2015.h"
43 
44 /* -------------------------------------------------------------------------
45  * static members
46  * ----------------------------------------------------------------------- */
49 
50 /* -------------------------------------------------------------------------
51  * MSAbstractLaneChangeModel-methods
52  * ----------------------------------------------------------------------- */
53 
54 void
56  myAllowOvertakingRight = oc.getBool("lanechange.overtake-right");
57  myLCOutput = oc.isSet("lanechange-output");
58 }
59 
60 
63  if (MSGlobals::gLateralResolution > 0 && lcm != LCM_SL2015 && lcm != LCM_DEFAULT) {
64  throw ProcessError("Lane change model '" + toString(lcm) + "' is not compatible with sublane simulation");
65  }
66  switch (lcm) {
67  case LCM_DK2008:
68  return new MSLCM_DK2008(v);
69  case LCM_LC2013:
70  return new MSLCM_LC2013(v);
71  case LCM_SL2015:
72  return new MSLCM_SL2015(v);
73  case LCM_DEFAULT:
75  return new MSLCM_LC2013(v);
76  } else {
77  return new MSLCM_SL2015(v);
78  }
79  default:
80  throw ProcessError("Lane change model '" + toString(lcm) + "' not implemented");
81  }
82 }
83 
84 
86  myVehicle(v),
87  myOwnState(0),
88  myLaneChangeCompletion(1.0),
89  myLaneChangeDirection(0),
90  myLateralspeed(0),
91  myAlreadyChanged(false),
92  myShadowLane(0),
93  myCarFollowModel(v.getCarFollowModel()),
94  myModel(model),
95  myLastLaneChangeOffset(0),
96  myAmOpposite(false) {
97 }
98 
99 
101 }
102 
103 
104 bool
106  if (neighLeader == 0) {
107  return false;
108  }
109  // Congested situation are relevant only on highways (maxSpeed > 70km/h)
110  // and congested on German Highways means that the vehicles have speeds
111  // below 60km/h. Overtaking on the right is allowed then.
112  if ((myVehicle.getLane()->getSpeedLimit() <= 70.0 / 3.6) || (neighLeader->getLane()->getSpeedLimit() <= 70.0 / 3.6)) {
113 
114  return false;
115  }
116  if (myVehicle.congested() && neighLeader->congested()) {
117  return true;
118  }
119  return false;
120 }
121 
122 
123 
124 bool
125 MSAbstractLaneChangeModel::predInteraction(const std::pair<MSVehicle*, SUMOReal>& leader) {
126  if (leader.first == 0) {
127  return false;
128  }
129  // let's check it on highways only
130  if (leader.first->getSpeed() < (80.0 / 3.6)) {
131  return false;
132  }
133  return leader.second < myCarFollowModel.interactionGap(&myVehicle, leader.first->getSpeed());
134 }
135 
136 
137 bool
139  if (&source->getEdge() != &target->getEdge()) {
141  }
144  myLaneChangeDirection = direction;
148  return true;
149  } else {
150  primaryLaneChanged(source, target, direction);
151  return false;
152  }
153 }
154 
155 
156 void
158  initLastLaneChangeOffset(direction);
160  source->leftByLaneChange(&myVehicle);
162  target->enteredByLaneChange(&myVehicle);
163  if (myLCOutput) {
164  OutputDevice& of = OutputDevice::getDeviceByOption("lanechange-output");
165  of.openTag("change");
167  of.writeAttr(SUMO_ATTR_TIME, time2string(MSNet::getInstance()->getCurrentTimeStep()));
168  of.writeAttr(SUMO_ATTR_FROM, source->getID());
169  of.writeAttr(SUMO_ATTR_TO, target->getID());
170  of.writeAttr(SUMO_ATTR_DIR, direction);
173  of.closeTag();
174  }
175  changed();
176 }
177 
178 
179 bool
181  const bool pastBefore = pastMidpoint();
183  return !pastBefore && pastMidpoint();
184 }
185 
186 
187 void
189  UNUSED_PARAMETER(reason);
195 }
196 
197 
198 MSLane*
201  // initialize shadow lane
202  const SUMOReal overlap = myVehicle.getLateralOverlap();
203  if (myVehicle.getID() == "disabled") {
204  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " posLat=" << myVehicle.getLateralPositionOnLane() << " overlap=" << overlap << "\n";
205  }
206  if (overlap > NUMERICAL_EPS ||
207  // "reserve" target lane even when there is no overlap yet
209  const int shadowDirection = myVehicle.getLateralPositionOnLane() < 0 ? -1 : 1;
210  return lane->getParallelLane(shadowDirection);
211  } else {
212  return 0;
213  }
214  } else {
215  return 0;
216  }
217 }
218 
219 
220 void
222  if (myShadowLane != 0) {
223  if (myVehicle.getID() == "disabled") {
224  std::cout << SIMTIME << " cleanupShadowLane\n";
225  }
227  myShadowLane = 0;
228  }
229  for (std::vector<MSLane*>::const_iterator it = myShadowFurtherLanes.begin(); it != myShadowFurtherLanes.end(); ++it) {
230  if (myVehicle.getID() == "disabled") {
231  std::cout << SIMTIME << " cleanupShadowLane2\n";
232  }
233  (*it)->resetPartialOccupation(&myVehicle);
234  }
235  myShadowFurtherLanes.clear();
237 }
238 
239 
240 bool
242  int ret = myVehicle.influenceChangeDecision(state);
243  return ret != state;
244 }
245 
246 
247 void
249  if (dir > 0) {
251  } else if (dir < 0) {
253  }
254 }
255 
256 void
258  if (myShadowLane != 0) {
259  if (gDebugFlag4) {
260  std::cout << SIMTIME << " updateShadowLane\n";
261  }
263  }
265  std::vector<MSLane*> passed;
266  if (myShadowLane != 0) {
268  const std::vector<MSLane*>& further = myVehicle.getFurtherLanes();
269  const std::vector<SUMOReal>& furtherPosLat = myVehicle.getFurtherLanesPosLat();
270  assert(further.size() == furtherPosLat.size());
271  for (int i = (int)further.size() - 1; i >= 0; --i) {
272  if (furtherPosLat[i] == myVehicle.getLateralPositionOnLane()) {
273  MSLane* shadowFurther = getShadowLane(further[i]);
274  if (shadowFurther != 0) {
275  passed.push_back(shadowFurther);
276  }
277  } else {
278  // vehicle end is still on the original lane after lane changing
279  break;
280  }
281  }
282  passed.push_back(myShadowLane);
283  } else {
285  WRITE_WARNING("Vehicle '" + myVehicle.getID() + "' could not finish continuous lane change (lane disappeared) time=" +
286  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
288  }
289  }
290  if (gDebugFlag4) std::cout << SIMTIME << " updateShadowLane veh=" << myVehicle.getID()
291  << " newShadowLane=" << Named::getIDSecure(myShadowLane)
292  << "\n before:" << " myShadowFurtherLanes=" << toString(myShadowFurtherLanes) << " passed=" << toString(passed)
293  << "\n";
295  if (gDebugFlag4) std::cout
296  << "\n after:" << " myShadowFurtherLanes=" << toString(myShadowFurtherLanes) << "\n";
297 }
298 
299 
300 int
302  if (isChangingLanes()) {
303  if (pastMidpoint()) {
304  return -myLaneChangeDirection;
305  } else {
306  return myLaneChangeDirection;
307  }
308  } else if (myShadowLane == 0) {
309  return 0;
310  } else {
311  assert(&myShadowLane->getEdge() == &myVehicle.getLane()->getEdge());
313  }
314 }
315 
316 
317 SUMOReal
320  return myLaneChangeDirection * angleOffset;
321 }
322 
323 
324 SUMOTime
327 }
328 
329 
330 void
332  //std::cout << SIMTIME << " veh=" << myVehicle.getID() << " @=" << &myVehicle << " set shadow approaching=" << link->getViaLaneOrLane()->getID() << "\n";
333  myApproachedByShadow.push_back(link);
334 }
335 
336 void
338  for (std::vector<MSLink*>::iterator it = myApproachedByShadow.begin(); it != myApproachedByShadow.end(); ++it) {
339  //std::cout << SIMTIME << " veh=" << myVehicle.getID() << " @=" << &myVehicle << " remove shadow approaching=" << (*it)->getViaLaneOrLane()->getID() << "\n";
340  (*it)->removeApproaching(&myVehicle);
341  }
342  myApproachedByShadow.clear();
343 }
344 
345 
346 void
349  myAlreadyChanged = true;
350 }
A lane change model developed by J. Erdmann.
Definition: MSLCM_SL2015.h:44
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:571
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:82
long long int SUMOTime
Definition: SUMOTime.h:43
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
std::vector< SUMOReal > myShadowFurtherLanesPosLat
virtual bool predInteraction(const std::pair< MSVehicle *, SUMOReal > &leader)
bool congested() const
Definition: MSVehicle.h:596
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
int getShadowDirection() const
return the direction in which the current shadow lane lies
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
Wants go to the right.
static bool myLCOutput
whether to record lane-changing
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:59
SUMOReal getCenterOnEdge() const
Definition: MSLane.h:905
void leftByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2016
MSLane * myShadowLane
A lane that is partially occupied by the front of the vehicle but that is not the primary lane...
Wants go to the left.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:2561
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
SUMOReal updateFurtherLanes(std::vector< MSLane * > &furtherLanes, std::vector< SUMOReal > &furtherLanesPosLat, const std::vector< MSLane * > &passedLanes)
update a vector of further lanes and return the new backPos
Definition: MSVehicle.cpp:2147
#define SIMTIME
Definition: SUMOTime.h:70
Right blinker lights are switched on.
Definition: MSVehicle.h:1000
SUMOReal getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:406
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
const std::string & getID() const
Returns the id.
Definition: Named.h:66
LaneChangeModel
The vehicle changes lanes (micro only) XXX: What if a vehicle changes lanes and passes a junction sim...
A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013...
Definition: MSLCM_LC2013.h:55
Left blinker lights are switched on.
Definition: MSVehicle.h:1002
bool cancelRequest(int state)
whether the influencer cancels the given request
std::vector< MSLane * > myNoPartiallyOccupatedByShadow
SUMOReal getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane ...
Definition: MSVehicle.cpp:3442
bool pastMidpoint() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
virtual void resetPartialOccupation(MSVehicle *v)
Removes the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:225
virtual SUMOReal interactionGap(const MSVehicle *const veh, SUMOReal vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel.cpp:175
void enteredByLaneChange(MSVehicle *v)
Definition: MSLane.cpp:2023
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:1561
std::vector< MSLane * > myShadowFurtherLanes
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
SUMOReal getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:472
int myLaneChangeDirection
direction of the lane change maneuver -1 means right, 1 means left
virtual void changed()=0
static void initGlobalOptions(const OptionsCont &oc)
init global model parameters
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
virtual SUMOReal setPartialOccupation(MSVehicle *v)
Sets the information about a vehicle lapping into this lane.
Definition: MSLane.cpp:212
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:3095
int myOwnState
The current state of the vehicle.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:503
bool gDebugFlag4
Definition: StdDefs.cpp:94
SUMOReal getAngleOffset() const
return the angle offset during a continuous change maneuver
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:2653
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
const std::vector< SUMOReal > & getFurtherLanesPosLat() const
Definition: MSVehicle.h:658
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
const std::vector< MSLane * > & getFurtherLanes() const
Definition: MSVehicle.h:654
LaneChangeAction
The state of a vehicle's lane-change behavior.
SUMOTime remainingTime() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
A storage for options typed value containers)
Definition: OptionsCont.h:99
static SUMOReal gLateralResolution
Definition: MSGlobals.h:89
SUMOReal myLateralspeed
The lateral offset during a continuous LaneChangeManeuver.
SUMOReal getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:441
The abstract direction of a link.
A lane change model developed by D. Krajzewicz between 2004 and 2010.
Definition: MSLCM_DK2008.h:47
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1061
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1053
#define NUMERICAL_EPS
Definition: config.h:161
std::vector< MSLink * > myApproachedByShadow
links which are approached by the shadow vehicle
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:487
SUMOReal myLaneChangeCompletion
progress of the lane change maneuver 0:started, 1:complete
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:3714
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:86
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
bool myAlreadyChanged
whether the vehicle has already moved this step
const MSCFModel & myCarFollowModel
The vehicle's car following model.
bool myAmOpposite
whether the vehicle is driving in the opposite direction
MSAbstractLaneChangeModel(MSVehicle &v, const LaneChangeModel model)
Constructor.
Interface for lane-change models.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
const std::string & getID() const
Returns the name of the vehicle.
virtual bool congested(const MSVehicle *const neighLeader)
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
virtual ~MSAbstractLaneChangeModel()
Destructor.