Eclipse SUMO - Simulation of Urban MObility
MSLCM_LC2013.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
20 // A lane change model developed by J. Erdmann
21 // based on the model of D. Krajzewicz developed between 2004 and 2011 (MSLCM_DK2004)
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <iostream>
34 #include <microsim/MSEdge.h>
35 #include <microsim/MSLane.h>
36 #include <microsim/MSDriverState.h>
37 #include <microsim/MSNet.h>
38 #include "MSLCM_LC2013.h"
39 
40 
41 // ===========================================================================
42 // variable definitions
43 // ===========================================================================
44 #define LOOK_FORWARD (double)10.
45 
46 #define JAM_FACTOR (double)1.
47 
48 #define LCA_RIGHT_IMPATIENCE (double)-1.
49 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27.
50 
51 #define LOOK_AHEAD_MIN_SPEED 0.0
52 #define LOOK_AHEAD_SPEED_MEMORY 0.9
53 
54 #define HELP_DECEL_FACTOR (double)1.0
55 
56 #define HELP_OVERTAKE (double)(10.0 / 3.6)
57 #define MIN_FALLBEHIND (double)(7.0 / 3.6)
58 
59 // allow overtaking to the right below this speed difference
60 #define OVERTAKE_RIGHT_THRESHOLD (double)(5/3.6)
61 
62 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0
63 #define URGENCY (double)2.0
64 #define OPPOSITE_URGENCY (double)5.0
65 
66 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane
67 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right
68 
69 #define ROUNDABOUT_DIST_FACTOR (double)10.0 // Must be >=1.0, serves an alternative way of decreasing sense lc-urgency by multiplying the distance along the next roundabout
70 
71 #define KEEP_RIGHT_HEADWAY (double)2.0
72 #define MAX_ONRAMP_LENGTH (double)200.
73 #define TURN_LANE_DIST (double)200.0 // the distance at which a lane leading elsewhere is considered to be a turn-lane that must be avoided
74 
75 #define LC_RESOLUTION_SPEED_LAT (double)0.5 // the lateral speed (in m/s) for a standing vehicle which was unable to finish a continuous LC in time (in case mySpeedLatStanding==0), see #3771
76 #define LC_ASSUMED_DECEL (double)1.0 // the minimal constant deceleration assumed to estimate the duration of a continuous lane-change at its initiation.
77 
78 #define REACT_TO_STOPPED_DISTANCE 100
79 
80 // ===========================================================================
81 // debug defines
82 // ===========================================================================
83 //#define DEBUG_PATCH_SPEED
84 //#define DEBUG_INFORMED
85 //#define DEBUG_INFORMER
86 //#define DEBUG_CONSTRUCTOR
87 //#define DEBUG_WANTS_CHANGE
88 //#define DEBUG_SLOW_DOWN
89 //#define DEBUG_COOPERATE
90 //#define DEBUG_SAVE_BLOCKER_LENGTH
91 
92 //#define DEBUG_COND (myVehicle.getID() == "disabled")
93 #define DEBUG_COND (myVehicle.isSelected())
94 //#define DEBUG_COND (false)
95 
96 // ===========================================================================
97 // member method definitions
98 // ===========================================================================
101  mySpeedGainProbability(0),
102  myKeepRightProbability(0),
103  myLeadingBlockerLength(0),
104  myLeftSpace(0),
105  myLookAheadSpeed(LOOK_AHEAD_MIN_SPEED),
106  myStrategicParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_STRATEGIC_PARAM, 1)),
107  myCooperativeParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_COOPERATIVE_PARAM, 1)),
108  mySpeedGainParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_SPEEDGAIN_PARAM, 1)),
109  myKeepRightParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_KEEPRIGHT_PARAM, 1)),
110  myOppositeParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_OPPOSITE_PARAM, 1)),
111  myLookaheadLeft(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_LOOKAHEADLEFT, 2.0)),
112  mySpeedGainRight(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_SPEEDGAINRIGHT, 0.1)),
113  myAssertive(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_ASSERTIVE, 1)),
114  myOvertakeRightParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_OVERTAKE_RIGHT, 0)),
115  myExperimentalParam1(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_EXPERIMENTAL1, 0)) {
117 #ifdef DEBUG_CONSTRUCTOR
118  if (DEBUG_COND) {
119  std::cout << SIMTIME
120  << " create lcModel veh=" << myVehicle.getID()
121  << " lcStrategic=" << myStrategicParam
122  << " lcCooperative=" << myCooperativeParam
123  << " lcSpeedGain=" << mySpeedGainParam
124  << " lcKeepRight=" << myKeepRightParam
125  << "\n";
126  }
127 #endif
128 }
129 
131  changed();
132 }
133 
134 
135 void
139 }
140 
141 
142 bool
144  return DEBUG_COND;
145 }
146 
147 
148 int
150  int laneOffset,
152  int blocked,
153  const std::pair<MSVehicle*, double>& leader,
154  const std::pair<MSVehicle*, double>& neighLead,
155  const std::pair<MSVehicle*, double>& neighFollow,
156  const MSLane& neighLane,
157  const std::vector<MSVehicle::LaneQ>& preb,
158  MSVehicle** lastBlocked,
159  MSVehicle** firstBlocked) {
160 
161 #ifdef DEBUG_WANTS_CHANGE
162  if (DEBUG_COND) {
163  std::cout << "\nWANTS_CHANGE\n" << SIMTIME
164  << std::setprecision(gPrecision)
165  << " veh=" << myVehicle.getID()
166  << " lane=" << myVehicle.getLane()->getID()
167  << " pos=" << myVehicle.getPositionOnLane()
168  << " posLat=" << myVehicle.getLateralPositionOnLane()
169  << " speed=" << myVehicle.getSpeed()
170  << " considerChangeTo=" << (laneOffset == -1 ? "right" : "left")
171  << "\n";
172  }
173 #endif
174 
175  const int result = _wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
176 
177 #ifdef DEBUG_WANTS_CHANGE
178  if (DEBUG_COND) {
179  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " result=" << toString((LaneChangeAction)result) << " blocked=" << toString((LaneChangeAction)blocked) << "\n\n\n";
180  }
181 #endif
182 
183  return result;
184 }
185 
186 
187 double
188 MSLCM_LC2013::patchSpeed(const double min, const double wanted, const double max, const MSCFModel& cfModel) {
189 
190 #ifdef DEBUG_PATCH_SPEED
191  if (DEBUG_COND) {
192  std::cout << "\nPATCH_SPEED\n"
193  << SIMTIME
194  << " veh=" << myVehicle.getID()
195  << " lane=" << myVehicle.getLane()->getID()
196  << " pos=" << myVehicle.getPositionOnLane()
197  << " v=" << myVehicle.getSpeed()
198  << " min=" << min
199  << " wanted=" << wanted
200  << " max=" << max
201  << "\n";
202  }
203 #endif
204 
205  // negative min speed may be passed when using ballistic updated
206  const double newSpeed = _patchSpeed(MAX2(min, 0.0), wanted, max, cfModel);
207 
208 #ifdef DEBUG_PATCH_SPEED
209  if (DEBUG_COND) {
210  const std::string patched = (wanted != newSpeed ? " patched=" + toString(newSpeed) : "");
211  std::cout << patched
212  << "\n";
213  }
214 #endif
215 
216  return newSpeed;
217 }
218 
219 
220 double
221 MSLCM_LC2013::_patchSpeed(const double min, const double wanted, const double max, const MSCFModel& cfModel) {
222  int state = myOwnState;
223 #ifdef DEBUG_PATCH_SPEED
224  if (DEBUG_COND) {
225  std::cout
226  << "\n" << SIMTIME << std::setprecision(gPrecision)
227  << " patchSpeed state=" << toString((LaneChangeAction)state) << " myLCAccelerationAdvices=" << toString(myLCAccelerationAdvices)
228  << " \nspeed=" << myVehicle.getSpeed()
229  << " min=" << min
230  << " wanted=" << wanted << std::endl;
231  }
232 #endif
233 
234  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#2
235  double MAGIC_offset = 1.;
236  // if we want to change and have a blocking leader and there is enough room for him in front of us
237  if (myLeadingBlockerLength != 0) {
238  double space = myLeftSpace - myLeadingBlockerLength - MAGIC_offset - myVehicle.getVehicleType().getMinGap();
239 #ifdef DEBUG_PATCH_SPEED
240  if (DEBUG_COND) {
241  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " myLeadingBlockerLength=" << myLeadingBlockerLength << " space=" << space << "\n";
242  }
243 #endif
244  if (space > 0) { // XXX space > -MAGIC_offset
245  // compute speed for decelerating towards a place which allows the blocking leader to merge in in front
246  double safe = cfModel.stopSpeed(&myVehicle, myVehicle.getSpeed(), space);
247  // if we are approaching this place
248  if (safe < wanted) {
249  // return this speed as the speed to use
250 #ifdef DEBUG_PATCH_SPEED
251  if (DEBUG_COND) {
252  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " slowing down for leading blocker, safe=" << safe << (safe + NUMERICAL_EPS < min ? " (not enough)" : "") << "\n";
253  }
254 #endif
255  return MAX2(min, safe);
256  }
257  }
258  }
259 
260  double nVSafe = wanted;
261  bool gotOne = false;
262  const double coopWeight = MAX2(0.0, MIN2(1.0, myCooperativeParam));
263  for (std::vector<double>::const_iterator i = myLCAccelerationAdvices.begin(); i != myLCAccelerationAdvices.end(); ++i) {
264  double a = (*i);
265  double v = myVehicle.getSpeed() + ACCEL2SPEED(a);
266 
267  if (v >= min && v <= max && (MSGlobals::gSemiImplicitEulerUpdate
268  // ballistic update: (negative speeds may appear, e.g. min<0, v<0), BUT:
269  // XXX: LaneChanging returns -1 to indicate no restrictions, which leads to probs here (Leo), refs. #2577
270  // As a quick fix, we just dismiss cases where v=-1
271  // VERY rarely (whenever a requested help-acceleration is really indicated by v=-1)
272  // this can lead to failing lane-change attempts, though)
273  || v != -1)) {
274  nVSafe = MIN2(v * coopWeight + (1 - coopWeight) * wanted, nVSafe);
275  gotOne = true;
276 #ifdef DEBUG_PATCH_SPEED
277  if (DEBUG_COND) {
278  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " got nVSafe=" << nVSafe << "\n";
279  }
280 #endif
281  } else {
282  if (v < min) {
283 #ifdef DEBUG_PATCH_SPEED
284  if (DEBUG_COND) {
285  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " ignoring low nVSafe=" << v << " min=" << min << "\n";
286  }
287 #endif
288  } else {
289 #ifdef DEBUG_PATCH_SPEED
290  if (DEBUG_COND) {
291  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " ignoring high nVSafe=" << v << " max=" << max << "\n";
292  }
293 #endif
294  }
295  }
296  }
297 
298  if (gotOne && !myDontBrake) { // XXX: myDontBrake is initialized as false and seems not to be changed anywhere... What's its purpose???
299 #ifdef DEBUG_PATCH_SPEED
300  if (DEBUG_COND) {
301  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " got vSafe\n";
302  }
303 #endif
304  return nVSafe;
305  }
306 
307  // check whether the vehicle is blocked
308  if ((state & LCA_WANTS_LANECHANGE) != 0 && (state & LCA_BLOCKED) != 0) {
309  if ((state & LCA_STRATEGIC) != 0) {
310  // necessary decelerations are controlled via vSafe. If there are
311  // none it means we should speed up
312 #ifdef DEBUG_PATCH_SPEED
313  if (DEBUG_COND) {
314  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_WANTS_LANECHANGE (strat, no vSafe)\n";
315  }
316 #endif
317  return (max + wanted) / (double) 2.0;
318  } else if ((state & LCA_COOPERATIVE) != 0) {
319  // only minor adjustments in speed should be done
320  if ((state & LCA_BLOCKED_BY_LEADER) != 0) {
321 #ifdef DEBUG_PATCH_SPEED
322  if (DEBUG_COND) {
323  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_BLOCKED_BY_LEADER (coop)\n";
324  }
325 #endif
326  if (wanted >= 0.) {
327  return (MAX2(0., min) + wanted) / (double) 2.0;
328  } else {
329  return wanted;
330  }
331  }
332  if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) {
333 #ifdef DEBUG_PATCH_SPEED
334  if (DEBUG_COND) {
335  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_BLOCKED_BY_FOLLOWER (coop)\n";
336  }
337 #endif
338  return (max + wanted) / (double) 2.0;
339  }
340  //} else { // VARIANT_16
341  // // only accelerations should be performed
342  // if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) {
343  // if (gDebugFlag2) std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_BLOCKED_BY_FOLLOWER\n";
344  // return (max + wanted) / (double) 2.0;
345  // }
346  }
347  }
348 
349  /*
350  // decelerate if being a blocking follower
351  // (and does not have to change lanes)
352  if ((state & LCA_AMBLOCKINGFOLLOWER) != 0) {
353  if (fabs(max - myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle)) < 0.001 && min == 0) { // !!! was standing
354  if (gDebugFlag2) std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGFOLLOWER (standing)\n";
355  return 0;
356  }
357  if (gDebugFlag2) std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGFOLLOWER\n";
358 
359  //return min; // VARIANT_3 (brakeStrong)
360  return (min + wanted) / (double) 2.0;
361  }
362  if ((state & LCA_AMBACKBLOCKER) != 0) {
363  if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle) && min == 0) { // !!! was standing
364  if (gDebugFlag2) std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_AMBACKBLOCKER (standing)\n";
365  //return min; VARIANT_9 (backBlockVSafe)
366  return nVSafe;
367  }
368  }
369  if ((state & LCA_AMBACKBLOCKER_STANDING) != 0) {
370  if (gDebugFlag2) std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_AMBACKBLOCKER_STANDING\n";
371  //return min;
372  return nVSafe;
373  }
374  */
375 
376  // accelerate if being a blocking leader or blocking follower not able to brake
377  // (and does not have to change lanes)
378  if ((state & LCA_AMBLOCKINGLEADER) != 0) {
379 #ifdef DEBUG_PATCH_SPEED
380  if (DEBUG_COND) {
381  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGLEADER\n";
382  }
383 #endif
384  return (max + wanted) / (double) 2.0;
385  }
386 
387  if ((state & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) {
388 #ifdef DEBUG_PATCH_SPEED
389  if (DEBUG_COND) {
390  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGFOLLOWER_DONTBRAKE\n";
391  }
392 #endif
393  /*
394  // VARIANT_4 (dontbrake)
395  if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle) && min == 0) { // !!! was standing
396  return wanted;
397  }
398  return (min + wanted) / (double) 2.0;
399  */
400  }
401  if (!myVehicle.getLane()->getEdge().hasLaneChanger()) {
402  // remove chaning information if on a road with a single lane
403  changed();
404  }
405  return wanted;
406 }
407 
408 
409 void*
410 MSLCM_LC2013::inform(void* info, MSVehicle* sender) {
411  UNUSED_PARAMETER(sender);
412  Info* pinfo = (Info*)info;
413  assert(pinfo->first >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
414  addLCSpeedAdvice(pinfo->first);
415  myOwnState |= pinfo->second;
416 #ifdef DEBUG_INFORMED
417  if (DEBUG_COND) {
418  std::cout << SIMTIME
419  << " veh=" << myVehicle.getID()
420  << " informedBy=" << sender->getID()
421  << " info=" << pinfo->second
422  << " vSafe=" << pinfo->first
423  << "\n";
424  }
425 #endif
426  delete pinfo;
427  return (void*) true;
428 }
429 
430 double
431 MSLCM_LC2013::overtakeDistance(const MSVehicle* follower, const MSVehicle* leader, const double gap, double followerSpeed, double leaderSpeed) {
432  followerSpeed = followerSpeed == INVALID_SPEED ? follower->getSpeed() : followerSpeed;
433  leaderSpeed = leaderSpeed == INVALID_SPEED ? leader->getSpeed() : leaderSpeed;
434  double overtakeDist = (gap // drive to back of leader
435  + leader->getVehicleType().getLengthWithGap() // drive to front of leader
436  + follower->getVehicleType().getLength() // follower back reaches leader front
437  + leader->getCarFollowModel().getSecureGap( // save gap to leader
438  leader, follower, leaderSpeed, followerSpeed, follower->getCarFollowModel().getMaxDecel()));
439  return MAX2(overtakeDist, 0.);
440 }
441 
442 
443 double
445  int blocked,
446  int dir,
447  const std::pair<MSVehicle*, double>& neighLead,
448  double remainingSeconds) {
449  double plannedSpeed = MIN2(myVehicle.getSpeed(),
451  for (std::vector<double>::const_iterator i = myLCAccelerationAdvices.begin(); i != myLCAccelerationAdvices.end(); ++i) {
452  const double a = *i;
453  if (a >= -myVehicle.getCarFollowModel().getMaxDecel()) {
454  plannedSpeed = MIN2(plannedSpeed, myVehicle.getSpeed() + ACCEL2SPEED(a));
455  }
456  }
457 #ifdef DEBUG_INFORMER
458  if (DEBUG_COND) {
459  std::cout << "\nINFORM_LEADER"
460  << "\nspeed=" << myVehicle.getSpeed() << " planned=" << plannedSpeed << "\n";
461  }
462 #endif
463 
464  const MSVehicle* const nv = neighLead.first;
465  if (nv == nullptr) {
466  // not overtaking
467  return plannedSpeed;
468  }
469  const double neighNextSpeed = nv->getSpeed() - ACCEL2SPEED(MAX2(1.0, -nv->getAcceleration()));
470  double neighNextGap;
472  neighNextGap = neighLead.second + SPEED2DIST(neighNextSpeed - plannedSpeed);
473  } else {
474  neighNextGap = neighLead.second + SPEED2DIST((nv->getSpeed() + neighNextSpeed) / 2) - SPEED2DIST((myVehicle.getSpeed() + plannedSpeed) / 2);
475  }
476  if ((blocked & LCA_BLOCKED_BY_LEADER) != 0) {
477 #ifdef DEBUG_INFORMER
478  if (DEBUG_COND) {
479  std::cout << " blocked by leader nv=" << nv->getID() << " nvSpeed=" << nv->getSpeed() << " needGap="
481  }
482 #endif
483  // decide whether we want to overtake the leader or follow it
484  double overtakeTime;
485  const double overtakeDist = overtakeDistance(&myVehicle, nv, neighLead.second);
486  const double dv = plannedSpeed - nv->getSpeed();
487 
488  if (dv > 0) {
489  overtakeTime = overtakeDist / dv;
490  } else {
491  // -> set overtakeTime to something indicating impossibility of overtaking
492  overtakeTime = remainingSeconds + 1;
493  }
494 
495 #ifdef DEBUG_INFORMER
496  if (DEBUG_COND) {
497  std::cout << SIMTIME << " informLeader() of " << myVehicle.getID()
498  << "\nnv = " << nv->getID()
499  << "\nplannedSpeed = " << plannedSpeed
500  << "\nleaderSpeed = " << nv->getSpeed()
501  << "\nmyLeftSpace = " << myLeftSpace
502  << "\nremainingSeconds = " << remainingSeconds
503  << "\novertakeDist = " << overtakeDist
504  << "\novertakeTime = " << overtakeTime
505  << std::endl;
506  }
507 #endif
508 
509  if ((dv < 0
510  // overtaking on the right on an uncongested highway is forbidden (noOvertakeLCLeft)
512  // not enough space to overtake?
514  // using brakeGap() without headway seems adequate in a situation where the obstacle (the lane end) is not moving [XXX implemented in branch ticket860, can be used in general if desired, refs. #2575] (Leo).
516  // not enough time to overtake? (skipped for a stopped leader [currently only for ballistic update XXX: check if appropriate for euler, too, refs. #2575] to ensure that it can be overtaken if only enough space is exists) (Leo)
517  || (remainingSeconds < overtakeTime && (MSGlobals::gSemiImplicitEulerUpdate || !nv->isStopped())))
518  // opposite driving and must overtake
519  && !(isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
520  // cannot overtake
521  msgPass.informNeighLeader(new Info(std::numeric_limits<double>::max(), dir | LCA_AMBLOCKINGLEADER), &myVehicle);
522  // slow down smoothly to follow leader
523  // account for minor decelerations by the leader (dawdling)
524  const double targetSpeed = MAX2(
526  myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighNextGap, neighNextSpeed, nv->getCarFollowModel().getMaxDecel()));
527  if (targetSpeed < myVehicle.getSpeed()) {
528  // slow down smoothly to follow leader
529  const double decel = remainingSeconds == 0. ? myVehicle.getCarFollowModel().getMaxDecel() :
531  MAX2(MIN_FALLBEHIND, (myVehicle.getSpeed() - targetSpeed) / remainingSeconds));
532  const double nextSpeed = MIN2(plannedSpeed, myVehicle.getSpeed() - ACCEL2SPEED(decel));
533 #ifdef DEBUG_INFORMER
534  if (DEBUG_COND) {
535  std::cout << SIMTIME
536  << " cannot overtake leader nv=" << nv->getID()
537  << " dv=" << dv
538  << " myLookAheadSpeed=" << myLookAheadSpeed
539  << " myLeftSpace=" << myLeftSpace
540  << " overtakeDist=" << overtakeDist
541  << " overtakeTime=" << overtakeTime
542  << " remainingSeconds=" << remainingSeconds
543  << " currentGap=" << neighLead.second
545  << " neighNextSpeed=" << neighNextSpeed
546  << " neighNextGap=" << neighNextGap
547  << " targetSpeed=" << targetSpeed
548  << " nextSpeed=" << nextSpeed
549  << "\n";
550  }
551 #endif
552  addLCSpeedAdvice(nextSpeed);
553  return nextSpeed;
554  } else {
555  // leader is fast enough anyway
556 #ifdef DEBUG_INFORMER
557  if (DEBUG_COND) {
558  std::cout << SIMTIME
559  << " cannot overtake fast leader nv=" << nv->getID()
560  << " dv=" << dv
561  << " myLookAheadSpeed=" << myLookAheadSpeed
562  << " myLeftSpace=" << myLeftSpace
563  << " overtakeDist=" << overtakeDist
564  << " myLeadingBlockerLength=" << myLeadingBlockerLength
565  << " overtakeTime=" << overtakeTime
566  << " remainingSeconds=" << remainingSeconds
567  << " currentGap=" << neighLead.second
568  << " targetSpeed=" << targetSpeed
569  << "\n";
570  }
571 #endif
572  addLCSpeedAdvice(targetSpeed);
573  return plannedSpeed;
574  }
575  } else {
576  // overtaking, leader should not accelerate
577 #ifdef DEBUG_INFORMER
578  if (DEBUG_COND) {
579  std::cout << SIMTIME
580  << " wants to overtake leader nv=" << nv->getID()
581  << " dv=" << dv
582  << " overtakeDist=" << overtakeDist
583  << " remainingSeconds=" << remainingSeconds
584  << " overtakeTime=" << overtakeTime
585  << " currentGap=" << neighLead.second
587  << "\n";
588  }
589 #endif
590  msgPass.informNeighLeader(new Info(nv->getSpeed(), dir | LCA_AMBLOCKINGLEADER), &myVehicle);
591  return -1; // XXX: using -1 is ambiguous for the ballistic update! Currently this is being catched in patchSpeed() (Leo), consider returning INVALID_SPEED, refs. #2577
592  }
593  } else { // (remainUnblocked)
594  // we are not blocked now. make sure we stay far enough from the leader
595  const double targetSpeed = MAX2(
597  myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighNextGap, neighNextSpeed, nv->getCarFollowModel().getMaxDecel()));
598  addLCSpeedAdvice(targetSpeed);
599 #ifdef DEBUG_INFORMER
600  if (DEBUG_COND) {
601  std::cout << " not blocked by leader nv=" << nv->getID()
602  << " nvSpeed=" << nv->getSpeed()
603  << " gap=" << neighLead.second
604  << " neighNextSpeed=" << neighNextSpeed
605  << " neighNextGap=" << neighNextGap
607  << " targetSpeed=" << targetSpeed
608  << "\n";
609  }
610 #endif
611  return MIN2(targetSpeed, plannedSpeed);
612  }
613 }
614 
615 void
617  int blocked,
618  int dir,
619  const std::pair<MSVehicle*, double>& neighFollow,
620  double remainingSeconds,
621  double plannedSpeed) {
622 
623  MSVehicle* nv = neighFollow.first;
624  const double plannedAccel = SPEED2ACCEL(MAX2(MIN2(myCarFollowModel.getMaxAccel(), plannedSpeed - myVehicle.getSpeed()), -myCarFollowModel.getMaxDecel()));
625 
626 #ifdef DEBUG_INFORMER
627  if (DEBUG_COND) {
628  std::cout << "\nINFORM_FOLLOWER"
629  << "\nspeed=" << myVehicle.getSpeed() << " planned=" << plannedSpeed << "\n";
630  }
631 
632 #endif
633  if ((blocked & LCA_BLOCKED_BY_FOLLOWER) != 0 && nv != nullptr) {
634 #ifdef DEBUG_INFORMER
635  if (DEBUG_COND) {
636  std::cout << " blocked by follower nv=" << nv->getID() << " nvSpeed=" << nv->getSpeed() << " needGap="
637  << nv->getCarFollowModel().getSecureGap(nv, &myVehicle, nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel()) << " planned=" << plannedSpeed << "\n";
638  }
639 #endif
640 
641  // are we fast enough to cut in without any help?
642  if (MAX2(plannedSpeed, 0.) - nv->getSpeed() >= HELP_OVERTAKE) {
643  const double neededGap = nv->getCarFollowModel().getSecureGap(nv, &myVehicle, nv->getSpeed(), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
644  if ((neededGap - neighFollow.second) / remainingSeconds < (MAX2(plannedSpeed, 0.) - nv->getSpeed())) {
645 #ifdef DEBUG_INFORMER
646  if (DEBUG_COND) {
647  std::cout << " wants to cut in before nv=" << nv->getID() << " without any help." << "\nneededGap = " << neededGap << "\n";
648  }
649 #endif
650  // follower might even accelerate but not to much
651  // XXX: I don't understand this. The needed gap was determined for nv->getSpeed(), not for (plannedSpeed - HELP_OVERTAKE)?! (Leo), refs. #2578
652  msgPass.informNeighFollower(new Info(MAX2(plannedSpeed, 0.) - HELP_OVERTAKE, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
653  return;
654  }
655  }
656 
657  // decide whether we will request help to cut in before the follower or allow to be overtaken
658 
659  // PARAMETERS
660  // assume other vehicle will assume the equivalent of 1 second of
661  // maximum deceleration to help us (will probably be spread over
662  // multiple seconds)
663  // -----------
664  const double helpDecel = nv->getCarFollowModel().getMaxDecel() * HELP_DECEL_FACTOR;
665 
666  // follower's new speed in next step
667  double neighNewSpeed;
668  // follower's new speed after 1s.
669  double neighNewSpeed1s;
670  // velocity difference, gap after follower-deceleration
671  double dv, decelGap;
672 
674  // euler
675  neighNewSpeed = MAX2(0., nv->getSpeed() - ACCEL2SPEED(helpDecel));
676  neighNewSpeed1s = MAX2(0., nv->getSpeed() - helpDecel); // TODO: consider introduction of a configurable anticipationTime here (see far below in the !blocked part). Refs. #2578
677  // change in the gap between ego and blocker over 1 second (not STEP!)
678  // XXX: though here it is calculated as if it were one step!? (Leo) Refs. #2578
679  dv = plannedSpeed - neighNewSpeed1s; // XXX: what is this quantity (if TS!=1)?
680  // new gap between follower and self in case the follower does brake for 1s
681  // XXX: if the step-length is not 1s., this is not the gap after 1s. deceleration!
682  // And this formula overestimates the real gap. Isn't that problematic? (Leo)
683  // Below, it seems that decelGap > secureGap is taken to indicate the possibility
684  // to cut in within the next time-step. However, this is not the case, if TS<1s.,
685  // since decelGap is (not exactly, though!) the gap after 1s. Refs. #2578
686  decelGap = neighFollow.second + dv;
687  } else {
688  // ballistic
689  // negative newSpeed-extrapolation possible, if stop lies within the next time-step
690  // XXX: this code should work for the euler case as well, since gapExtrapolation() takes
691  // care of this, but for TS!=1 we will have different behavior (see previous remark) Refs. #2578
692  neighNewSpeed = nv->getSpeed() - ACCEL2SPEED(helpDecel);
693  neighNewSpeed1s = nv->getSpeed() - helpDecel;
694 
695  dv = myVehicle.getSpeed() - nv->getSpeed(); // current velocity difference
696  decelGap = myCarFollowModel.gapExtrapolation(1., neighFollow.second, myVehicle.getSpeed(),
697  nv->getSpeed(), plannedAccel, -helpDecel, myVehicle.getMaxSpeedOnLane(), nv->getMaxSpeedOnLane());
698  }
699 
700  const double secureGap = nv->getCarFollowModel().getSecureGap(nv, &myVehicle, MAX2(neighNewSpeed1s, 0.),
701  MAX2(plannedSpeed, 0.), myVehicle.getCarFollowModel().getMaxDecel());
702 
703  const double onRampThreshold = myVehicle.getLane()->getSpeedLimit() * 0.8 * myExperimentalParam1 * (1 - myVehicle.getImpatience());
704 
705 #ifdef DEBUG_INFORMER
706  if (DEBUG_COND) {
707  std::cout << SIMTIME
708  << " speed=" << myVehicle.getSpeed()
709  << " plannedSpeed=" << plannedSpeed
710  << " threshold=" << onRampThreshold
711  << " neighNewSpeed=" << neighNewSpeed
712  << " neighNewSpeed1s=" << neighNewSpeed1s
713  << " dv=" << dv
714  << " gap=" << neighFollow.second
715  << " decelGap=" << decelGap
716  << " secureGap=" << secureGap
717  << "\n";
718  }
719 #endif
720  // prevent vehicles on an on ramp stopping the main flow
721  if (dir == LCA_MLEFT
723  && neighNewSpeed1s < onRampThreshold) {
724  return;
725  }
726 
727  if (decelGap > 0 && decelGap >= secureGap) {
728  // XXX: This does not assure that the leader can cut in in the next step if TS < 1 (see above)
729  // this seems to be supposed in the following (euler code)...?! (Leo) Refs. #2578
730 
731  // if the blocking follower brakes it could help
732  // how hard does it actually need to be?
733  // to be safe in the next step the following equation has to hold for the follower's vsafe:
734  // vsafe <= followSpeed(gap=currentGap - SPEED2DIST(vsafe), ...)
735  double vsafe, vsafe1;
736 
738  // euler
739  // we compute an upper bound on vsafe by doing the computation twice
740  vsafe1 = MAX2(neighNewSpeed, nv->getCarFollowModel().followSpeed(
741  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed), plannedSpeed, myCarFollowModel.getMaxDecel()));
742  vsafe = MAX2(neighNewSpeed, nv->getCarFollowModel().followSpeed(
743  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed - vsafe1), plannedSpeed, myCarFollowModel.getMaxDecel()));
744  assert(vsafe <= vsafe1);
745  } else {
746  // ballistic
747 
748  // XXX: This block should actually do as well for euler update (TODO: test!), refs #2575
749  // we compute an upper bound on vsafe
750  // next step's gap without help deceleration (nv's speed assumed constant)
751  double nextGap = myCarFollowModel.gapExtrapolation(TS,
752  neighFollow.second, myVehicle.getSpeed(),
753  nv->getSpeed(), plannedAccel, 0,
755 #ifdef DEBUG_INFORMER
756  if (DEBUG_COND) {
757  std::cout << "nextGap=" << nextGap << " (without help decel) \n";
758  }
759 #endif
760 
761  // NOTE: the second argument of MIN2() can get larger than nv->getSpeed()
762  vsafe1 = MIN2(nv->getSpeed(), MAX2(neighNewSpeed,
764  nv->getSpeed(), nextGap,
765  MAX2(0., plannedSpeed),
767 
768 
769  // next step's gap with possibly less than maximal help deceleration (in case vsafe1 > neighNewSpeed)
770  double decel2 = SPEED2ACCEL(nv->getSpeed() - vsafe1);
772  neighFollow.second, myVehicle.getSpeed(),
773  nv->getSpeed(), plannedAccel, -decel2,
775 
776  // vsafe = MAX(neighNewSpeed, safe speed assuming next_gap)
777  // Thus, the gap resulting from vsafe is larger or equal to next_gap
778  // in contrast to the euler case, where nv's follow speed doesn't depend on the actual speed,
779  // we need to assure, that nv doesn't accelerate
780  vsafe = MIN2(nv->getSpeed(), MAX2(neighNewSpeed,
782  nv->getSpeed(), nextGap,
783  MAX2(0., plannedSpeed),
785 
786  assert(vsafe >= vsafe1 - NUMERICAL_EPS);
787 
788 #ifdef DEBUG_INFORMER
789  if (DEBUG_COND) {
790  std::cout << "nextGap=" << nextGap
791  << " (with vsafe1 and help decel) \nvsafe1=" << vsafe1
792  << " vsafe=" << vsafe
793  << "\n";
794  }
795 #endif
796 
797  // For subsecond simulation, this might not lead to secure gaps for a long time,
798  // we seek to establish a secure gap as soon as possible
799  double nextSecureGap = nv->getCarFollowModel().getSecureGap(nv, &myVehicle, vsafe, plannedSpeed, myCarFollowModel.getMaxDecel());
800 
801  if (nextGap < nextSecureGap) {
802  // establish a secureGap as soon as possible
803  vsafe = neighNewSpeed;
804  }
805 
806 #ifdef DEBUG_INFORMER
807  if (DEBUG_COND) {
808  std::cout << "nextGap=" << nextGap
809  << " minNextSecureGap=" << nextSecureGap
810  << " vsafe=" << vsafe << "\n";
811  }
812 #endif
813 
814  }
815  msgPass.informNeighFollower(
816  new Info(vsafe, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
817 
818 #ifdef DEBUG_INFORMER
819  if (DEBUG_COND) {
820  std::cout << " wants to cut in before nv=" << nv->getID()
821  << " vsafe1=" << vsafe1 << " vsafe=" << vsafe
822  << " newSecGap="
823  << nv->getCarFollowModel().getSecureGap(nv, &myVehicle, vsafe,
824  plannedSpeed,
826  << "\n";
827  }
828 #endif
829  } else if ((MSGlobals::gSemiImplicitEulerUpdate && dv > 0 && dv * remainingSeconds > (secureGap - decelGap + POSITION_EPS))
830  || (!MSGlobals::gSemiImplicitEulerUpdate && dv > 0 && dv * (remainingSeconds - 1) > secureGap - decelGap + POSITION_EPS)
831  ) {
832 
833  // XXX: Alternative formulation (encapsulating differences of euler and ballistic) TODO: test, refs. #2575
834  // double eventualGap = myCarFollowModel.gapExtrapolation(remainingSeconds - 1., decelGap, plannedSpeed, neighNewSpeed1s);
835  // } else if (eventualGap > secureGap + POSITION_EPS) {
836 
837 
838  // NOTE: This case corresponds to the situation, where some time is left to perform the lc
839  // For the ballistic case this is interpreted as follows:
840  // If the follower breaks with helpDecel for one second, this vehicle maintains the plannedSpeed,
841  // and both continue with their speeds for remainingSeconds seconds the gap will suffice for a laneChange
842  // For the euler case we had the following comment:
843  // 'decelerating once is sufficient to open up a large enough gap in time', but:
844  // XXX: 1) Decelerating *once* does not necessarily lead to the gap decelGap! (if TS<1s.) (Leo)
845  // 2) Probably, the if() for euler should test for dv * (remainingSeconds-1) > ..., too ?!, refs. #2578
846  msgPass.informNeighFollower(new Info(neighNewSpeed, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
847 #ifdef DEBUG_INFORMER
848  if (DEBUG_COND) {
849  std::cout << " wants to cut in before nv=" << nv->getID() << " (eventually)\n";
850  }
851 #endif
852  } else if (dir == LCA_MRIGHT && !myAllowOvertakingRight && !nv->congested()) {
853  // XXX: check if this requires a special treatment for the ballistic update, refs. #2575
854  const double vhelp = MAX2(neighNewSpeed, HELP_OVERTAKE);
855  msgPass.informNeighFollower(new Info(vhelp, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
856 #ifdef DEBUG_INFORMER
857  if (DEBUG_COND) {
858  std::cout << " wants to cut in before nv=" << nv->getID() << " (nv cannot overtake right)\n";
859  }
860 #endif
861  } else {
862  double vhelp = MAX2(nv->getSpeed(), myVehicle.getSpeed() + HELP_OVERTAKE);
863  //if (dir == LCA_MRIGHT && myVehicle.getWaitingSeconds() > LCA_RIGHT_IMPATIENCE &&
864  // nv->getSpeed() > myVehicle.getSpeed()) {
865  if (nv->getSpeed() > myVehicle.getSpeed() &&
866  ((dir == LCA_MRIGHT && myVehicle.getWaitingSeconds() > LCA_RIGHT_IMPATIENCE) // NOTE: it might be considered to use myVehicle.getAccumulatedWaitingSeconds() > LCA_RIGHT_IMPATIENCE instead (Leo). Refs. #2578
867  || (dir == LCA_MLEFT && plannedSpeed > CUT_IN_LEFT_SPEED_THRESHOLD) // VARIANT_22 (slowDownLeft)
868  // XXX this is a hack to determine whether the vehicles is on an on-ramp. This information should be retrieved from the network itself
870  )) {
871  // let the follower slow down to increase the likelihood that later vehicles will be slow enough to help
872  // follower should still be fast enough to open a gap
873  // XXX: The probability for that success would be larger if the slow down of the appropriate following vehicle
874  // would take place without the immediate follower slowing down. We might consider to model reactions of
875  // vehicles that are not immediate followers. (Leo) -> see ticket #2532
876  vhelp = MAX2(neighNewSpeed, myVehicle.getSpeed() + HELP_OVERTAKE);
877 #ifdef DEBUG_INFORMER
878  if (DEBUG_COND) {
879  // NOTE: the condition labeled "VARIANT_22" seems to imply that this could as well concern the *left* follower?! (Leo)
880  // Further, vhelp might be larger than nv->getSpeed(), so the request issued below is not to slow down!? (see below) Refs. #2578
881  std::cout << " wants right follower to slow down a bit\n";
882  }
883 #endif
885  // euler
886  if ((nv->getSpeed() - myVehicle.getSpeed()) / helpDecel < remainingSeconds) {
887 
888 #ifdef DEBUG_INFORMER
889  if (DEBUG_COND) {
890  // NOTE: the condition labeled "VARIANT_22" seems to imply that this could as well concern the *left* follower?! Refs. #2578
891  std::cout << " wants to cut in before right follower nv=" << nv->getID() << " (eventually)\n";
892  }
893 #endif
894  // XXX: I don't understand. This vhelp might be larger than nv->getSpeed() but the above condition seems to rely
895  // on the reasoning that if nv breaks with helpDecel for remaining Seconds, nv will be so slow, that this
896  // vehicle will be able to cut in. But nv might have overtaken this vehicle already (or am I missing sth?). (Leo)
897  // Ad: To my impression, the intention behind allowing larger speeds for the blocking follower is to prevent a
898  // situation, where an overlapping follower keeps blocking the ego vehicle. Refs. #2578
899  msgPass.informNeighFollower(new Info(vhelp, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
900  return;
901  }
902  } else {
903 
904  // ballistic (this block is a bit different to the logic in the euler part, but in general suited to work on euler as well.. must be tested <- TODO, refs. #2575)
905  // estimate gap after remainingSeconds.
906  // Assumptions:
907  // (A1) leader continues with currentSpeed. (XXX: That might be wrong: Think of accelerating on an on-ramp or of a congested region ahead!)
908  // (A2) follower breaks with helpDecel.
909  const double gapAfterRemainingSecs = myCarFollowModel.gapExtrapolation(
910  remainingSeconds, neighFollow.second, myVehicle.getSpeed(), nv->getSpeed(), 0, -helpDecel, myVehicle.getMaxSpeedOnLane(), nv->getMaxSpeedOnLane());
911  const double secureGapAfterRemainingSecs = nv->getCarFollowModel().getSecureGap(nv, &myVehicle,
912  MAX2(nv->getSpeed() - remainingSeconds * helpDecel, 0.), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel());
913  if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) { // XXX: here it would be wise to check whether there is enough space for eventual braking if the maneuver doesn't succeed
914 #ifdef DEBUG_INFORMER
915  if (DEBUG_COND) {
916  std::cout << " wants to cut in before follower nv=" << nv->getID() << " (eventually)\n";
917  }
918 #endif
919  // NOTE: ballistic uses neighNewSpeed instead of vhelp, see my note above. (Leo)
920  // TODO: recheck if this might cause suboptimal behaviour in some LC-situations. Refs. #2578
921  msgPass.informNeighFollower(new Info(neighNewSpeed, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
922  return;
923  }
924  }
925 
926 
927  }
928 
929 #ifdef DEBUG_INFORMER
930  if (DEBUG_COND) {
931  std::cout << SIMTIME
932  << " veh=" << myVehicle.getID()
933  << " informs follower " << nv->getID()
934  << " vhelp=" << vhelp
935  << "\n";
936  }
937 #endif
938 
939  msgPass.informNeighFollower(new Info(vhelp, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
940  // This follower is supposed to overtake us. Slow down smoothly to allow this.
941  const double overtakeDist = overtakeDistance(nv, &myVehicle, neighFollow.second, vhelp, plannedSpeed);
942  // speed difference to create a sufficiently large gap
943  const double needDV = overtakeDist / remainingSeconds;
944  // make sure the deceleration is not to strong (XXX: should be assured in finalizeSpeed -> TODO: remove the MAX2 if agreed) -> prob with possibly non-existing maximal deceleration for som CF Models(?) Refs. #2578
946 
947 #ifdef DEBUG_INFORMER
948  if (DEBUG_COND) {
949  std::cout << SIMTIME
950  << " veh=" << myVehicle.getID()
951  << " wants to be overtaken by=" << nv->getID()
952  << " overtakeDist=" << overtakeDist
953  << " vneigh=" << nv->getSpeed()
954  << " vhelp=" << vhelp
955  << " needDV=" << needDV
956  << " vsafe=" << myLCAccelerationAdvices.back()
957  << "\n";
958  }
959 #endif
960  }
961  } else if (neighFollow.first != 0 && (blocked & LCA_BLOCKED_BY_LEADER)) {
962  // we are not blocked by the follower now, make sure it remains that way
963  // XXX: Does the below code for the euler case really assure that? Refs. #2578
964  double vsafe, vsafe1;
966  // euler
967  MSVehicle* nv = neighFollow.first;
968  vsafe1 = nv->getCarFollowModel().followSpeed(
969  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
970  vsafe = nv->getCarFollowModel().followSpeed(
971  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed - vsafe1), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
972  // NOTE: since vsafe1 > nv->getSpeed() is possible, we don't have vsafe1 < vsafe < nv->getSpeed here (similar pattern above works differently)
973 
974  } else {
975  // ballistic
976  // XXX This should actually do for euler and ballistic cases (TODO: test!) Refs. #2575
977 
978  double anticipationTime = 1.;
979  double anticipatedSpeed = MIN2(myVehicle.getSpeed() + plannedAccel * anticipationTime, myVehicle.getMaxSpeedOnLane());
980  double anticipatedGap = myCarFollowModel.gapExtrapolation(anticipationTime, neighFollow.second, myVehicle.getSpeed(), nv->getSpeed(),
981  plannedAccel, 0, myVehicle.getMaxSpeedOnLane(), nv->getMaxSpeedOnLane());
982  double secureGap = nv->getCarFollowModel().getSecureGap(nv, &myVehicle, nv->getSpeed(), anticipatedSpeed, myCarFollowModel.getMaxDecel());
983 
984  // propose follower speed corresponding to first estimation of gap
985  vsafe = nv->getCarFollowModel().followSpeed(
986  nv, nv->getSpeed(), anticipatedGap, plannedSpeed, myCarFollowModel.getMaxDecel());
987  double helpAccel = SPEED2ACCEL(vsafe - nv->getSpeed()) / anticipationTime;
988 
989  if (anticipatedGap > secureGap) {
990  // follower may accelerate, implying vhelp >= vsafe >= nv->getSpeed()
991  // calculate gap for the assumed acceleration
992  anticipatedGap = myCarFollowModel.gapExtrapolation(anticipationTime, neighFollow.second, myVehicle.getSpeed(), nv->getSpeed(),
993  plannedAccel, helpAccel, myVehicle.getMaxSpeedOnLane(), nv->getMaxSpeedOnLane());
994  double anticipatedHelpSpeed = MIN2(nv->getSpeed() + anticipationTime * helpAccel, nv->getMaxSpeedOnLane());
995  secureGap = nv->getCarFollowModel().getSecureGap(nv, &myVehicle, anticipatedHelpSpeed, anticipatedSpeed, myCarFollowModel.getMaxDecel());
996  if (anticipatedGap < secureGap) {
997  // don't accelerate
998  vsafe = nv->getSpeed();
999  }
1000  } else {
1001  // follower is too fast, implying that vhelp <= vsafe <= nv->getSpeed()
1002  // we use the above vhelp
1003  }
1004  }
1005  msgPass.informNeighFollower(new Info(vsafe, dir), &myVehicle);
1006 
1007 #ifdef DEBUG_INFORMER
1008  if (DEBUG_COND) {
1009  std::cout << " wants to cut in before non-blocking follower nv=" << nv->getID() << "\n";
1010  }
1011 #endif
1012  }
1013 }
1014 
1015 
1016 void
1019  // keep information about strategic change direction
1020  if (!isChangingLanes()) {
1022  }
1024  myLeftSpace = 0;
1025  myLCAccelerationAdvices.clear();
1026  myDontBrake = false;
1027  // truncate to work around numerical instability between different builds
1028  mySpeedGainProbability = ceil(mySpeedGainProbability * 100000.0) * 0.00001;
1029  myKeepRightProbability = ceil(myKeepRightProbability * 100000.0) * 0.00001;
1031  // disturb lateral position directly
1032  const double oldPosLat = myVehicle.getLateralPositionOnLane();
1033  const double deltaPosLat = OUProcess::step(oldPosLat,
1035  MAX2(NUMERICAL_EPS, (1 - mySigma) * 100), mySigma) - oldPosLat;
1036  const double scaledDelta = deltaPosLat * myVehicle.getSpeed() / myVehicle.getLane()->getSpeedLimit();
1037  myVehicle.setLateralPositionOnLane(oldPosLat + scaledDelta);
1038  }
1039 }
1040 
1041 
1042 void
1044  myOwnState = 0;
1047  if (myVehicle.getBestLaneOffset() == 0) {
1048  // if we are not yet on our best lane there might still be unseen blockers
1049  // (during patchSpeed)
1051  myLeftSpace = 0;
1052  }
1054  myLCAccelerationAdvices.clear();
1055  myDontBrake = false;
1056 }
1057 
1058 
1059 int
1061  int laneOffset,
1063  int blocked,
1064  const std::pair<MSVehicle*, double>& leader,
1065  const std::pair<MSVehicle*, double>& neighLead,
1066  const std::pair<MSVehicle*, double>& neighFollow,
1067  const MSLane& neighLane,
1068  const std::vector<MSVehicle::LaneQ>& preb,
1069  MSVehicle** lastBlocked,
1070  MSVehicle** firstBlocked) {
1071  assert(laneOffset == 1 || laneOffset == -1);
1072  const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
1073  // compute bestLaneOffset
1074  MSVehicle::LaneQ curr, neigh, best;
1075  int bestLaneOffset = 0;
1076  // What do these "dists" mean? Please comment. (Leo) Ad: I now think the following:
1077  // currentDist is the distance that the vehicle can go on its route without having to
1078  // change lanes from the current lane. neighDist as currentDist for the considered target lane (i.e., neigh)
1079  // If this is true I suggest to put this into the docu of wantsChange()
1080  double currentDist = 0;
1081  double neighDist = 0;
1082  int currIdx = 0;
1083  MSLane* prebLane = myVehicle.getLane();
1084  if (prebLane->getEdge().isInternal()) {
1085  // internal edges are not kept inside the bestLanes structure
1086  prebLane = prebLane->getLinkCont()[0]->getLane();
1087  }
1088  // XXX: What does the following code do? Please comment. (Leo) Refs. #2578
1089  const bool checkOpposite = &neighLane.getEdge() != &myVehicle.getLane()->getEdge();
1090  const int prebOffset = (checkOpposite ? 0 : laneOffset);
1091  for (int p = 0; p < (int) preb.size(); ++p) {
1092  if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1093  assert(p + prebOffset < (int)preb.size());
1094  curr = preb[p];
1095  neigh = preb[p + prebOffset];
1096  currentDist = curr.length;
1097  neighDist = neigh.length;
1098  bestLaneOffset = curr.bestLaneOffset;
1099  if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1100 #ifdef DEBUG_WANTS_CHANGE
1101  if (DEBUG_COND) {
1102  std::cout << STEPS2TIME(currentTime)
1103  << " veh=" << myVehicle.getID()
1104  << " bestLaneOffsetOld=" << bestLaneOffset
1105  << " bestLaneOffsetNew=" << laneOffset
1106  << "\n";
1107  }
1108 #endif
1109  bestLaneOffset = prebOffset;
1110  }
1111  best = preb[p + bestLaneOffset];
1112  currIdx = p;
1113  break;
1114  }
1115  }
1116  // direction specific constants
1117  const bool right = (laneOffset == -1);
1118  if (isOpposite() && right) {
1119  neigh = preb[preb.size() - 1];
1120  curr = neigh;
1121  best = neigh;
1122  bestLaneOffset = -1;
1123  curr.bestLaneOffset = -1;
1124  neighDist = neigh.length;
1125  currentDist = curr.length;
1126  }
1127  double driveToNextStop = -std::numeric_limits<double>::max();
1128  if (myVehicle.nextStopDist() < std::numeric_limits<double>::max()
1130  // vehicle can always drive up to stop distance
1131  // @note this information is dynamic and thus not available in updateBestLanes()
1132  // @note: nextStopDist was compute before the vehicle moved
1133  driveToNextStop = myVehicle.nextStopDist();
1135 #ifdef DEBUG_WANTS_CHANGE
1136  if (DEBUG_COND) {
1137  std::cout << SIMTIME << std::setprecision(gPrecision) << " veh=" << myVehicle.getID()
1138  << " stopDist=" << myVehicle.nextStopDist()
1139  << " lastDist=" << myVehicle.getLastStepDist()
1140  << " stopPos=" << stopPos
1141  << " currentDist=" << currentDist
1142  << " neighDist=" << neighDist
1143  << "\n";
1144  }
1145 #endif
1146  currentDist = MAX2(currentDist, stopPos);
1147  neighDist = MAX2(neighDist, stopPos);
1148  }
1150  const int lca = (right ? LCA_RIGHT : LCA_LEFT);
1151  const int myLca = (right ? LCA_MRIGHT : LCA_MLEFT);
1152  const int lcaCounter = (right ? LCA_LEFT : LCA_RIGHT);
1153  const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1154  // keep information about being a leader/follower
1155  int ret = (myOwnState & 0xffff0000);
1156  int req = 0; // the request to change or stay
1157 
1158  ret = slowDownForBlocked(lastBlocked, ret);
1159  if (lastBlocked != firstBlocked) {
1160  ret = slowDownForBlocked(firstBlocked, ret);
1161  }
1162 
1163 #ifdef DEBUG_WANTS_CHANGE
1164  if (DEBUG_COND) {
1165  std::cout << SIMTIME
1166  << " veh=" << myVehicle.getID()
1167  << " _wantsChange state=" << myOwnState
1168  << " myLCAccelerationAdvices=" << toString(myLCAccelerationAdvices)
1169  << " firstBlocked=" << Named::getIDSecure(*firstBlocked)
1170  << " lastBlocked=" << Named::getIDSecure(*lastBlocked)
1171  << " leader=" << Named::getIDSecure(leader.first)
1172  << " leaderGap=" << leader.second
1173  << " neighLead=" << Named::getIDSecure(neighLead.first)
1174  << " neighLeadGap=" << neighLead.second
1175  << " neighFollow=" << Named::getIDSecure(neighFollow.first)
1176  << " neighFollowGap=" << neighFollow.second
1177  << "\n";
1178  }
1179 #endif
1180 
1181  // we try to estimate the distance which is necessary to get on a lane
1182  // we have to get on in order to keep our route
1183  // we assume we need something that depends on our velocity
1184  // and compare this with the free space on our wished lane
1185  //
1186  // if the free space is somehow(<-?) less than the space we need, we should
1187  // definitely try to get to the desired lane
1188  //
1189  // this rule forces our vehicle to change the lane if a lane changing is necessary soon
1190 
1191 
1192  // we do not want the lookahead distance to change all the time so we let it decay slowly
1193  // (in contrast, growth is applied instantaneously)
1196  } else {
1197  // memory decay factor for this action step
1198  const double memoryFactor = 1. - (1. - LOOK_AHEAD_SPEED_MEMORY) * myVehicle.getActionStepLengthSecs();
1199  assert(memoryFactor > 0.);
1201  (memoryFactor * myLookAheadSpeed + (1 - memoryFactor) * myVehicle.getSpeed()));
1202  }
1203  double laDist = myLookAheadSpeed * LOOK_FORWARD * myStrategicParam * (right ? 1 : myLookaheadLeft);
1204  laDist += myVehicle.getVehicleType().getLengthWithGap() * (double) 2.;
1205 
1206 
1207  if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped() && leader.second < (currentDist - posOnLane)) {
1208  // react to a stopped leader on the current lane
1209  // The value of laDist is doubled below for the check whether the lc-maneuver can be taken out
1210  // on the remaining distance (because the vehicle has to change back and forth). Therefore multiply with 0.5.
1211  laDist = 0.5 * (myVehicle.getVehicleType().getLengthWithGap()
1212  + leader.first->getVehicleType().getLengthWithGap()
1213  + leader.second);
1214  } else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped() && neighLead.second < (currentDist - posOnLane)) {
1215  // react to a stopped leader on the target lane (if it is the bestLane)
1217  + neighLead.first->getVehicleType().getLengthWithGap()
1218  + neighLead.second);
1219  }
1220 
1221  // free space that is available for changing
1222  //const double neighSpeed = (neighLead.first != 0 ? neighLead.first->getSpeed() :
1223  // neighFollow.first != 0 ? neighFollow.first->getSpeed() :
1224  // best.lane->getSpeedLimit());
1225  // @note: while this lets vehicles change earlier into the correct direction
1226  // it also makes the vehicles more "selfish" and prevents changes which are necessary to help others
1227 
1228 
1229 
1230  // Next we assign to roundabout edges a larger distance than to normal edges
1231  // in order to decrease sense of lc urgency and induce higher usage of inner roundabout lanes.
1232  const double roundaboutBonus = getRoundaboutDistBonus(curr, neigh, best);
1233  currentDist += roundaboutBonus;
1234  neighDist += roundaboutBonus;
1235 
1236  const double usableDist = MAX2(currentDist - posOnLane - best.occupation * JAM_FACTOR, driveToNextStop);
1237  //- (best.lane->getVehicleNumber() * neighSpeed)); // VARIANT 9 jfSpeed
1238  const double maxJam = MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1239  const double neighLeftPlace = MAX2((double) 0, neighDist - posOnLane - maxJam);
1240  const double vMax = myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle);
1241  // upper bound which will be restricted successively
1242  double thisLaneVSafe = vMax;
1243  const bool checkOverTakeRight = (!myAllowOvertakingRight
1244  && !myVehicle.congested()
1247 
1248 #ifdef DEBUG_WANTS_CHANGE
1249  if (DEBUG_COND) {
1250  std::cout << STEPS2TIME(currentTime)
1251  << " veh=" << myVehicle.getID()
1252  << " laSpeed=" << myLookAheadSpeed
1253  << " laDist=" << laDist
1254  << " currentDist=" << currentDist
1255  << " usableDist=" << usableDist
1256  << " bestLaneOffset=" << bestLaneOffset
1257  << " best.occupation=" << best.occupation
1258  << " best.length=" << best.length
1259  << "\n roundaboutBonus=" << roundaboutBonus
1260  << " maxJam=" << maxJam
1261  << " neighDist=" << neighDist
1262  << " neighLeftPlace=" << neighLeftPlace
1263  << "\n";
1264  }
1265 #endif
1266 
1267  bool changeLeftToAvoidOvertakeRight = false;
1268  if (changeToBest && bestLaneOffset == curr.bestLaneOffset
1269  && currentDistDisallows(usableDist, bestLaneOffset, laDist)) {
1271  ret = ret | lca | LCA_STRATEGIC | LCA_URGENT;
1272  } else {
1273  // VARIANT_20 (noOvertakeRight)
1274  if (neighLead.first != 0 && checkOverTakeRight && !right) {
1275  // check for slower leader on the left. we should not overtake but
1276  // rather move left ourselves (unless congested)
1277  MSVehicle* nv = neighLead.first;
1278  const double deltaV = MAX2(vMax - neighLane.getVehicleMaxSpeed(nv),
1279  myVehicle.getSpeed() - nv->getSpeed());
1280  if (deltaV > 0) {
1281  const double vMaxDecel = myCarFollowModel.getSpeedAfterMaxDecel(myVehicle.getSpeed());
1282  const double vSafeFollow = myCarFollowModel.followSpeed(
1283  &myVehicle, myVehicle.getSpeed(), neighLead.second, nv->getSpeed(), nv->getCarFollowModel().getMaxDecel());
1284  const double vStayBehind = nv->getSpeed() - HELP_OVERTAKE;
1285  double vSafe;
1286  if (vSafeFollow >= vMaxDecel) {
1287  vSafe = vSafeFollow;
1288  } else {
1289  vSafe = MAX2(vMaxDecel, vStayBehind);
1290  }
1292  vSafe = MAX2(vSafe, nv->getSpeed());
1293  }
1294  thisLaneVSafe = MIN2(thisLaneVSafe, vSafe);
1295  addLCSpeedAdvice(vSafe);
1296  // only generate impulse for overtaking left shortly before braking would be necessary
1297  const double deltaGapFuture = deltaV * 8;
1298  const double vSafeFuture = myCarFollowModel.followSpeed(
1299  &myVehicle, myVehicle.getSpeed(), neighLead.second - deltaGapFuture, nv->getSpeed(), nv->getCarFollowModel().getMaxDecel());
1300  if (vSafeFuture < vSafe) {
1301  const double relativeGain = deltaV / MAX2(vMax,
1304  changeLeftToAvoidOvertakeRight = true;
1305  }
1306 #ifdef DEBUG_WANTS_CHANGE
1307  if (DEBUG_COND) {
1308  std::cout << STEPS2TIME(currentTime)
1309  << " avoid overtaking on the right nv=" << nv->getID()
1310  << " deltaV=" << deltaV
1311  << " nvSpeed=" << nv->getSpeed()
1312  << " mySpeedGainProbability=" << mySpeedGainProbability
1313  << " planned acceleration =" << myLCAccelerationAdvices.back()
1314  << "\n";
1315  }
1316 #endif
1317  }
1318  }
1319  const double overtakeDist = (leader.first == 0 ? -1 :
1320  leader.second + myVehicle.getVehicleType().getLength() + leader.first->getVehicleType().getLengthWithGap());
1321  if (leader.first != 0 && leader.first->isStopped() && leader.second < REACT_TO_STOPPED_DISTANCE
1322  // current destination leaves enough space to overtake the leader
1323  && MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1324  // maybe do not overtake on the right at high speed
1325  && (!checkOverTakeRight || !right)
1326  && (neighLead.first == 0 || !neighLead.first->isStopped()
1327  // neighboring stopped vehicle leaves enough space to overtake leader
1328  || neighLead.second > overtakeDist)) {
1329  // avoid becoming stuck behind a stopped leader
1330  currentDist = myVehicle.getPositionOnLane() + leader.second;
1331 #ifdef DEBUG_WANTS_CHANGE
1332  if (DEBUG_COND) {
1333  std::cout << " veh=" << myVehicle.getID() << " overtake stopped leader=" << leader.first->getID()
1334  << " overtakeDist=" << overtakeDist
1335  << " remaining=" << MIN2(neighDist, currentDist) - posOnLane
1336  << "\n";
1337  }
1338 #endif
1339  ret = ret | lca | LCA_STRATEGIC | LCA_URGENT;
1340  } else if (!changeToBest && (currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1341  // the opposite lane-changing direction should be done than the one examined herein
1342  // we'll check whether we assume we could change anyhow and get back in time...
1343  //
1344  // this rule prevents the vehicle from moving in opposite direction of the best lane
1345  // unless the way till the end where the vehicle has to be on the best lane
1346  // is long enough
1347 #ifdef DEBUG_WANTS_CHANGE
1348  if (DEBUG_COND) {
1349  std::cout << " veh=" << myVehicle.getID() << " could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace << "\n";
1350  }
1351 #endif
1352  ret = ret | LCA_STAY | LCA_STRATEGIC;
1353  } else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1354  // the current lane is the best and a lane-changing would cause a situation
1355  // of which we assume we will not be able to return to the lane we have to be on.
1356  // this rule prevents the vehicle from leaving the current, best lane when it is
1357  // close to this lane's end
1358 #ifdef DEBUG_WANTS_CHANGE
1359  if (DEBUG_COND) {
1360  std::cout << " veh=" << myVehicle.getID() << " could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace << "\n";
1361  }
1362 #endif
1363  ret = ret | LCA_STAY | LCA_STRATEGIC;
1364  } else if (bestLaneOffset == 0
1365  && (leader.first == 0 || !leader.first->isStopped())
1366  && neigh.bestContinuations.back()->getLinkCont().size() != 0
1367  && roundaboutBonus == 0
1368  && !checkOpposite
1369  && neighDist < TURN_LANE_DIST) {
1370  // VARIANT_21 (stayOnBest)
1371  // we do not want to leave the best lane for a lane which leads elsewhere
1372  // unless our leader is stopped or we are approaching a roundabout
1373 #ifdef DEBUG_WANTS_CHANGE
1374  if (DEBUG_COND) {
1375  std::cout << " veh=" << myVehicle.getID() << " does not want to leave the bestLane (neighDist=" << neighDist << ")\n";
1376  }
1377 #endif
1378  ret = ret | LCA_STAY | LCA_STRATEGIC;
1379  }
1380  }
1381  // check for overriding TraCI requests
1382 #ifdef DEBUG_WANTS_CHANGE
1383  if (DEBUG_COND) {
1384  std::cout << STEPS2TIME(currentTime) << " veh=" << myVehicle.getID() << " ret=" << ret;
1385  }
1386 #endif
1387  // store state before canceling
1388  getCanceledState(laneOffset) |= ret;
1390  if ((ret & lcaCounter) != 0) {
1391  // we are not interested in traci requests for the opposite direction here
1392  ret &= ~(LCA_TRACI | lcaCounter | LCA_URGENT);
1393  }
1394 #ifdef DEBUG_WANTS_CHANGE
1395  if (DEBUG_COND) {
1396  std::cout << " retAfterInfluence=" << ret << "\n";
1397  }
1398 #endif
1399 
1400  if ((ret & LCA_STAY) != 0) {
1401  return ret;
1402  }
1403  if ((ret & LCA_URGENT) != 0) {
1404  // prepare urgent lane change maneuver
1405  // save the left space
1406  myLeftSpace = currentDist - posOnLane;
1407  if (changeToBest && abs(bestLaneOffset) > 1) {
1408  // there might be a vehicle which needs to counter-lane-change one lane further and we cannot see it yet
1409  myLeadingBlockerLength = MAX2((double)(right ? 20.0 : 40.0), myLeadingBlockerLength);
1410 #ifdef DEBUG_WANTS_CHANGE
1411  if (DEBUG_COND) {
1412  std::cout << " reserving space for unseen blockers myLeadingBlockerLength=" << myLeadingBlockerLength << "\n";
1413  }
1414 #endif
1415  }
1416 
1417  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#1
1418  // if there is a leader and he wants to change to the opposite direction
1419  saveBlockerLength(neighLead.first, lcaCounter);
1420  if (*firstBlocked != neighLead.first) {
1421  saveBlockerLength(*firstBlocked, lcaCounter);
1422  }
1423 
1424  const int remainingLanes = MAX2(1, abs(bestLaneOffset));
1425  const double urgency = isOpposite() ? OPPOSITE_URGENCY : URGENCY;
1426  const double remainingSeconds = ((ret & LCA_TRACI) == 0 ?
1427  //MAX2((double)STEPS2TIME(TS), (myLeftSpace-myLeadingBlockerLength) / MAX2(myLookAheadSpeed, NUMERICAL_EPS) / remainingLanes / urgency) :
1428  MAX2((double)STEPS2TIME(TS), myLeftSpace / MAX2(myLookAheadSpeed, NUMERICAL_EPS) / remainingLanes / urgency) :
1430  const double plannedSpeed = informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1431  // NOTE: for the ballistic update case negative speeds may indicate a stop request,
1432  // while informLeader returns -1 in that case. Refs. #2577
1433  if (plannedSpeed >= 0 || (!MSGlobals::gSemiImplicitEulerUpdate && plannedSpeed != -1)) {
1434  // maybe we need to deal with a blocking follower
1435  informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1436  }
1437 
1438 #ifdef DEBUG_WANTS_CHANGE
1439  if (DEBUG_COND) {
1440  std::cout << STEPS2TIME(currentTime)
1441  << " veh=" << myVehicle.getID()
1442  << " myLeftSpace=" << myLeftSpace
1443  << " remainingSeconds=" << remainingSeconds
1444  << " plannedSpeed=" << plannedSpeed
1445  << "\n";
1446  }
1447 #endif
1448 
1449  return ret;
1450  }
1451  // a high inconvenience prevents cooperative changes.
1452  const double inconvenience = MIN2((double)1.0, (laneOffset < 0
1455  const bool speedGainInconvenient = inconvenience > myCooperativeParam;
1456  const bool neighOccupancyInconvenient = neigh.lane->getBruttoOccupancy() > curr.lane->getBruttoOccupancy();
1457 
1458  // VARIANT_15
1459  if (roundaboutBonus > 0) {
1460 
1461 #ifdef DEBUG_WANTS_CHANGE
1462  if (DEBUG_COND) {
1463  std::cout << STEPS2TIME(currentTime)
1464  << " veh=" << myVehicle.getID()
1465  << " roundaboutBonus=" << roundaboutBonus
1466  << " myLeftSpace=" << myLeftSpace
1467  << "\n";
1468  }
1469 #endif
1470  // try to use the inner lanes of a roundabout to increase throughput
1471  // unless we are approaching the exit
1472  if (lca == LCA_LEFT) {
1473  // if inconvenience is not too high, request collaborative change (currently only for ballistic update)
1474  // TODO: test this for euler update! Refs. #2575
1475  if (MSGlobals::gSemiImplicitEulerUpdate || !neighOccupancyInconvenient) {
1476 // if(MSGlobals::gSemiImplicitEulerUpdate || !speedGainInconvenient){
1477  req = ret | lca | LCA_COOPERATIVE;
1478  }
1479  } else {
1480  // if inconvenience is not too high, request collaborative change (currently only for ballistic update)
1481  if (MSGlobals::gSemiImplicitEulerUpdate || neighOccupancyInconvenient) {
1482 // if(MSGlobals::gSemiImplicitEulerUpdate || speedGainInconvenient){
1483  req = ret | LCA_STAY | LCA_COOPERATIVE;
1484  }
1485  }
1486  if (!cancelRequest(req, laneOffset)) {
1487  return ret | req;
1488  }
1489  }
1490 
1491  // let's also regard the case where the vehicle is driving on a highway...
1492  // in this case, we do not want to get to the dead-end of an on-ramp
1493  if (right) {
1494  if (bestLaneOffset == 0 && myVehicle.getLane()->getSpeedLimit() > 80. / 3.6 && myLookAheadSpeed > SUMO_const_haltingSpeed) {
1495 #ifdef DEBUG_WANTS_CHANGE
1496  if (DEBUG_COND) {
1497  std::cout << " veh=" << myVehicle.getID() << " does not want to get stranded on the on-ramp of a highway\n";
1498  }
1499 #endif
1500  req = ret | LCA_STAY | LCA_STRATEGIC;
1501  if (!cancelRequest(req, laneOffset)) {
1502  return ret | req;
1503  }
1504  }
1505  }
1506  // --------
1507 
1508  // -------- make place on current lane if blocking follower
1509  //if (amBlockingFollowerPlusNB()) {
1510  // std::cout << myVehicle.getID() << ", " << currentDistAllows(neighDist, bestLaneOffset, laDist)
1511  // << " neighDist=" << neighDist
1512  // << " currentDist=" << currentDist
1513  // << "\n";
1514  //}
1515 
1517  && (!speedGainInconvenient)
1518  && ((myOwnState & myLca) != 0) // VARIANT_6 : counterNoHelp
1519  && (changeToBest || currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1520 
1521  // VARIANT_2 (nbWhenChangingToHelp)
1522 #ifdef DEBUG_COOPERATE
1523  if (DEBUG_COND) {
1524  std::cout << STEPS2TIME(currentTime)
1525  << " veh=" << myVehicle.getID()
1526  << " wantsChangeToHelp=" << (right ? "right" : "left")
1527  << " state=" << myOwnState
1528  << (((myOwnState & myLca) == 0) ? " (counter)" : "")
1529  << "\n";
1530  }
1531 #endif
1532  req = ret | lca | LCA_COOPERATIVE | LCA_URGENT ;//| LCA_CHANGE_TO_HELP;
1533  if (!cancelRequest(req, laneOffset)) {
1534  return ret | req;
1535  }
1536  }
1537 
1538  // --------
1539 
1540 
1543  //if ((blocked & LCA_BLOCKED) != 0) {
1544  // return ret;
1545  //}
1547 
1548  // -------- higher speed
1549  //if ((congested(neighLead.first) && neighLead.second < 20) || predInteraction(leader.first)) { //!!!
1550  // return ret;
1551  //}
1552 
1553  double neighLaneVSafe = neighLane.getVehicleMaxSpeed(&myVehicle);
1554 
1555  // we wish to anticipate future speeds. This is difficult when the leading
1556  // vehicles are still accelerating so we resort to comparing next speeds in this case
1557  const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1558  || (leader.first != 0 && leader.first->getAcceleration() > 0);
1559 
1560  if (acceleratingLeader) {
1561  // followSpeed allows acceleration for 1 step, to always compare speeds
1562  // after 1 second of acceleration we have call the function with a correct speed value
1563  // TODO: This should be explained better. Refs #2
1564  const double correctedSpeed = (myVehicle.getSpeed() + myVehicle.getCarFollowModel().getMaxAccel()
1566 
1567  if (neighLead.first == 0) {
1568  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, correctedSpeed, neighDist, 0, 0));
1569  } else {
1570  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(
1571  &myVehicle, correctedSpeed, neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1572  }
1573  if (leader.first == 0) {
1574  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, correctedSpeed, currentDist, 0, 0));
1575  } else {
1576  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(
1577  &myVehicle, correctedSpeed, leader.second, leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1578  }
1579  } else {
1580  if (neighLead.first == 0) {
1581  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.maximumSafeStopSpeed(neighDist, myVehicle.getSpeed(), true));
1582  } else {
1583  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.maximumSafeFollowSpeed(neighLead.second, myVehicle.getSpeed(),
1584  neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel(), true));
1585  }
1586  if (leader.first == 0) {
1587  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.maximumSafeStopSpeed(currentDist, myVehicle.getSpeed(), true));
1588  } else {
1589  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.maximumSafeFollowSpeed(leader.second, myVehicle.getSpeed(),
1590  leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel(), true));
1591  }
1592  }
1593 
1594  if (neighLane.getEdge().getPersons().size() > 0) {
1595  // react to pedestrians
1596  adaptSpeedToPedestrians(myVehicle.getLane(), thisLaneVSafe);
1597  adaptSpeedToPedestrians(&neighLane, neighLaneVSafe);
1598  }
1599 
1600  const double relativeGain = (neighLaneVSafe - thisLaneVSafe) / MAX2(neighLaneVSafe,
1602 
1603 #ifdef DEBUG_WANTS_CHANGE
1604  if (DEBUG_COND) {
1605  std::cout << STEPS2TIME(currentTime)
1606  << " veh=" << myVehicle.getID()
1607  << " currentDist=" << currentDist
1608  << " neighDist=" << neighDist
1609  << " thisVSafe=" << thisLaneVSafe
1610  << " neighVSafe=" << neighLaneVSafe
1611  << " relGain=" << toString(relativeGain, 8)
1612  << "\n";
1613  }
1614 #endif
1615 
1616  if (right) {
1617  // ONLY FOR CHANGING TO THE RIGHT
1618  if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1619  // ok, the current lane is faster than the right one...
1620  if (mySpeedGainProbability < 0) {
1622  //myKeepRightProbability /= 2.0;
1623  }
1624  } else {
1625  // ok, the current lane is not (much) faster than the right one
1626  // @todo recheck the 5 km/h discount on thisLaneVSafe, refs. #2068
1627 
1628  // do not promote changing to the left just because changing to the right is bad
1629  // XXX: The following code may promote it, though!? (recheck!)
1630  // (Think of small negative mySpeedGainProbability and larger negative relativeGain)
1631  // One might think of replacing '||' by '&&' to exclude that possibility...
1632  // Still, for negative relativeGain, we might want to decrease the inclination for
1633  // changing to the left. Another solution could be the seperation of mySpeedGainProbability into
1634  // two variables (one for left and one for right). Refs #2578
1635  if (mySpeedGainProbability < 0 || relativeGain > 0) {
1637  }
1638 
1639  // honor the obligation to keep right (Rechtsfahrgebot)
1640  // XXX consider fast approaching followers on the current lane. Refs #2578
1641  //const double vMax = myLookAheadSpeed;
1642  const double acceptanceTime = KEEP_RIGHT_ACCEPTANCE * vMax * MAX2((double)1, myVehicle.getSpeed()) / myVehicle.getLane()->getSpeedLimit();
1643  double fullSpeedGap = MAX2(0., neighDist - myVehicle.getCarFollowModel().brakeGap(vMax));
1644  double fullSpeedDrivingSeconds = MIN2(acceptanceTime, fullSpeedGap / vMax);
1645  if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1646  fullSpeedGap = MAX2(0., MIN2(fullSpeedGap,
1647  neighLead.second - myVehicle.getCarFollowModel().getSecureGap(&myVehicle, neighLead.first,
1648  vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1649  fullSpeedDrivingSeconds = MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1650  }
1651  // stay on the current lane if we cannot overtake a slow leader on the right
1652  if (checkOverTakeRight && leader.first != 0
1653  && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1654  fullSpeedGap = MIN2(fullSpeedGap, leader.second);
1655  fullSpeedDrivingSeconds = MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1656  const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) / MAX2(vMax,
1658  // tiebraker to avoid buridans paradox see #1312
1660  }
1661 
1662  const double deltaProb = (myChangeProbThresholdRight * (fullSpeedDrivingSeconds / acceptanceTime) / KEEP_RIGHT_TIME);
1664 
1665 #ifdef DEBUG_WANTS_CHANGE
1666  if (DEBUG_COND) {
1667  std::cout << STEPS2TIME(currentTime)
1668  << " veh=" << myVehicle.getID()
1669  << " vMax=" << vMax
1670  << " neighDist=" << neighDist
1671  << " brakeGap=" << myVehicle.getCarFollowModel().brakeGap(myVehicle.getSpeed())
1672  << " leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1673  << " secGap=" << (neighLead.first == 0 ? -1 : myVehicle.getCarFollowModel().getSecureGap(&myVehicle, neighLead.first,
1674  myVehicle.getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1675  << " acceptanceTime=" << acceptanceTime
1676  << " fullSpeedGap=" << fullSpeedGap
1677  << " fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1678  << " dProb=" << deltaProb
1679  << " myKeepRightProbability=" << myKeepRightProbability
1680  << "\n";
1681  }
1682 #endif
1684  req = ret | lca | LCA_KEEPRIGHT;
1685  if (!cancelRequest(req, laneOffset)) {
1686  return ret | req;
1687  }
1688  }
1689  }
1690 
1691 #ifdef DEBUG_WANTS_CHANGE
1692  if (DEBUG_COND) {
1693  std::cout << STEPS2TIME(currentTime)
1694  << " veh=" << myVehicle.getID()
1695  << " speed=" << myVehicle.getSpeed()
1696  << " mySpeedGainProbability=" << mySpeedGainProbability
1697  << " thisLaneVSafe=" << thisLaneVSafe
1698  << " neighLaneVSafe=" << neighLaneVSafe
1699  << " relativeGain=" << relativeGain
1700  << " blocked=" << blocked
1701  << "\n";
1702  }
1703 #endif
1704 
1706  && neighDist / MAX2((double) .1, myVehicle.getSpeed()) > 20.) { //./MAX2((double) .1, myVehicle.getSpeed())) { // -.1
1707  req = ret | lca | LCA_SPEEDGAIN;
1708  if (!cancelRequest(req, laneOffset)) {
1709  return ret | req;
1710  }
1711  }
1712  } else {
1713  // ONLY FOR CHANGING TO THE LEFT
1714  if (thisLaneVSafe > neighLaneVSafe) {
1715  // this lane is better
1716  if (mySpeedGainProbability > 0) {
1718  }
1719  } else if (thisLaneVSafe == neighLaneVSafe) {
1720  if (mySpeedGainProbability > 0) {
1722  }
1723  } else {
1724  // left lane is better
1726  }
1727  // VARIANT_19 (stayRight)
1728  //if (neighFollow.first != 0) {
1729  // MSVehicle* nv = neighFollow.first;
1730  // const double secGap = nv->getCarFollowModel().getSecureGap(nv, &myVehicle, nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel());
1731  // if (neighFollow.second < secGap * KEEP_RIGHT_HEADWAY) {
1732  // // do not change left if it would inconvenience faster followers
1733  // return ret | LCA_STAY | LCA_SPEEDGAIN;
1734  // }
1735  //}
1736 
1737 #ifdef DEBUG_WANTS_CHANGE
1738  if (DEBUG_COND) {
1739  std::cout << STEPS2TIME(currentTime)
1740  << " veh=" << myVehicle.getID()
1741  << " speed=" << myVehicle.getSpeed()
1742  << " mySpeedGainProbability=" << mySpeedGainProbability
1743  << " thisLaneVSafe=" << thisLaneVSafe
1744  << " neighLaneVSafe=" << neighLaneVSafe
1745  << " relativeGain=" << relativeGain
1746  << " blocked=" << blocked
1747  << "\n";
1748  }
1749 #endif
1750 
1752  && (relativeGain > NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1753  && neighDist / MAX2((double) .1, myVehicle.getSpeed()) > 20.) { // .1
1754  req = ret | lca | LCA_SPEEDGAIN;
1755  if (!cancelRequest(req, laneOffset)) {
1756  return ret | req;
1757  }
1758  }
1759  }
1760  // --------
1761  if (changeToBest && bestLaneOffset == curr.bestLaneOffset
1762  && relativeGain >= 0
1763  && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1764  // change towards the correct lane, speedwise it does not hurt
1765  req = ret | lca | LCA_STRATEGIC;
1766  if (!cancelRequest(req, laneOffset)) {
1767  return ret | req;
1768  }
1769  }
1770 #ifdef DEBUG_WANTS_CHANGE
1771  if (DEBUG_COND) {
1772  std::cout << STEPS2TIME(currentTime)
1773  << " veh=" << myVehicle.getID()
1774  << " mySpeedGainProbability=" << mySpeedGainProbability
1775  << " myKeepRightProbability=" << myKeepRightProbability
1776  << " thisLaneVSafe=" << thisLaneVSafe
1777  << " neighLaneVSafe=" << neighLaneVSafe
1778  << "\n";
1779  }
1780 #endif
1781 
1782  return ret;
1783 }
1784 
1785 
1786 double
1788  if (isOpposite()) {
1789  return 0;
1790  }
1791  const MSVehicle::LaneQ& inner = curr.lane == best.lane ? neigh : curr;
1792 
1793  int roundaboutJunctionsAhead = 0;
1794  bool enteredRoundabout = false;
1795  double seen = -myVehicle.getPositionOnLane();
1796 
1797  // first check using only normal lanes
1798  for (int i = 0; i < (int)best.bestContinuations.size(); i++) {
1799  MSLane* lane = best.bestContinuations[i];
1800  if (lane == nullptr) {
1801  lane = myVehicle.getLane();
1802  }
1803  if ((!enteredRoundabout || lane->getEdge().isRoundabout()) && i >= (int)inner.bestContinuations.size()) {
1804  // no bonus if we cannot continue on the inner lane until leaving the roundabout
1805 #ifdef DEBUG_WANTS_CHANGE
1806  if (debugVehicle()) {
1807  std::cout << " noBonus: inner does not continue (lane=" << lane->getID() << ")\n";
1808  }
1809 #endif
1810  return 0;
1811  }
1812  if (seen > 300) {
1813  // avoid long look-ahead
1814 #ifdef DEBUG_WANTS_CHANGE
1815  if (debugVehicle()) {
1816  std::cout << " noBonus: seen=" << seen << " (lane=" << lane->getID() << ")\n";
1817  }
1818 #endif
1819  return 0;
1820  }
1821  const MSJunction* junction = lane->getEdge().getToJunction();
1822  if (lane->getEdge().isRoundabout()) {
1823  enteredRoundabout = true;
1824  if (junction->getIncoming().size() + junction->getOutgoing().size() > 2) {
1825  roundaboutJunctionsAhead++;
1826  }
1827  } else if (enteredRoundabout) {
1828  // only check the first roundabout
1829  break;
1830  }
1831  seen += lane->getLength();
1832  }
1833  // no bonus if we want to take the next exit
1834  if (roundaboutJunctionsAhead < 2) {
1835  return 0;
1836  }
1837 
1838  // compute bonus value based on jamming and exact distances (taking into
1839  // account internal lanes)
1840  double occupancyOuter = 0;
1841  double occupancyInner = 0;
1842  double distanceInRoundabout = 0;
1843  MSLane* prevNormal = nullptr;
1844  MSLane* prevInner = nullptr;
1845  enteredRoundabout = false;
1846  for (int i = 0; i < (int)best.bestContinuations.size(); i++) {
1847  MSLane* lane = best.bestContinuations[i];
1848  if (lane == nullptr) {
1849  continue;
1850  }
1851  if (lane->getEdge().isRoundabout()) {
1852  enteredRoundabout = true;
1853  } else if (enteredRoundabout) {
1854  // only check the first roundabout
1855  break;
1856  }
1857  MSLane* via = nullptr;
1858  if (prevNormal != nullptr) {
1859  for (MSLink* link : prevNormal->getLinkCont()) {
1860  if (link->getLane() == lane) {
1861  via = link->getViaLane();
1862  }
1863  }
1864  }
1865  if (enteredRoundabout) {
1866  distanceInRoundabout += lane->getLength();
1867  if (via != nullptr) {
1868  distanceInRoundabout += via->getLength();
1869  }
1870  }
1871  // discount vehicles that are upstream from ego
1872  const double upstreamDiscount = &lane->getEdge() == &myVehicle.getLane()->getEdge()
1873  ? (lane->getLength() - myVehicle.getPositionOnLane()) / lane->getLength() : 1;
1874  prevNormal = lane;
1875  occupancyOuter += upstreamDiscount * lane->getBruttoVehLenSum();
1876  if (debugVehicle()) {
1877  std::cout << " lane=" << lane->getID() << " occ=" << lane->getBruttoVehLenSum() << " discount=" << upstreamDiscount << " outer=" << occupancyOuter << "\n";
1878  }
1879  if (via != nullptr) {
1880  occupancyOuter += via->getBruttoVehLenSum();
1881  if (debugVehicle()) {
1882  std::cout << " via=" << via->getID() << " occ=" << via->getBruttoVehLenSum() << " outer=" << occupancyOuter << "\n";
1883  }
1884  }
1885  if (i < (int)inner.bestContinuations.size()) {
1886  MSLane* innerLane = inner.bestContinuations[i];
1887  occupancyInner += upstreamDiscount * innerLane->getBruttoVehLenSum();
1888  if (debugVehicle()) {
1889  std::cout << " inner=" << innerLane->getID() << " occ=" << innerLane->getBruttoVehLenSum() << " discount=" << upstreamDiscount << " inner=" << occupancyInner << "\n";
1890  }
1891  if (prevInner != nullptr) {
1892  for (MSLink* link : prevInner->getLinkCont()) {
1893  if (link->getLane() == innerLane && link->getViaLane() != nullptr) {
1894  occupancyInner += link->getViaLane()->getBruttoVehLenSum();
1895  if (debugVehicle()) {
1896  std::cout << " innerVia=" << link->getViaLane()->getID() << " occ=" << link->getViaLane()->getBruttoVehLenSum() << " inner=" << occupancyInner << "\n";
1897  }
1898  }
1899  }
1900  }
1901  prevInner = innerLane;
1902  }
1903  }
1904 
1905 #ifdef DEBUG_WANTS_CHANGE
1906  if (debugVehicle()) {
1907  std::cout << " distanceInRoundabout=" << distanceInRoundabout
1908  << " roundaboutJunctionsAhead=" << roundaboutJunctionsAhead
1909  << " occupancyInner=" << occupancyInner
1910  << " occupancyOuter=" << occupancyOuter
1911  << "\n";
1912  }
1913 #endif
1914 
1915  const double maxOccupancy = MAX2(occupancyInner, occupancyOuter);
1916  if (maxOccupancy == 0) {
1917  // no bonues if the roundabout is empty
1918  return 0;
1919  }
1920  // give some bonus for using the inside lane at equal occupancy
1921  const double bonus = roundaboutJunctionsAhead * 7.5;
1922  const double relativeJam = (occupancyOuter - occupancyInner + bonus) / (maxOccupancy + bonus);
1923  // no bonus if the inner lane or the left lane entering the roundabout is jammed
1924  const double jamFactor = MAX2(0.0, relativeJam);
1925  const double result = distanceInRoundabout * jamFactor * myCooperativeParam * (ROUNDABOUT_DIST_FACTOR - 1.);
1926 #ifdef DEBUG_WANTS_CHANGE
1927  if (debugVehicle()) {
1928  std::cout << " relativeJam=" << relativeJam
1929  << " jamFactor=" << jamFactor
1930  << " distanceBonus=" << result
1931  << "\n";
1932  }
1933 #endif
1934  return result;
1935 }
1936 
1937 
1938 int
1940  // if this vehicle is blocking someone in front, we maybe decelerate to let him in
1941  if ((*blocked) != nullptr) {
1942  double gap = (*blocked)->getPositionOnLane() - (*blocked)->getVehicleType().getLength() - myVehicle.getPositionOnLane() - myVehicle.getVehicleType().getMinGap();
1943 #ifdef DEBUG_SLOW_DOWN
1944  if (DEBUG_COND) {
1945  std::cout << SIMTIME
1946  << " veh=" << myVehicle.getID()
1947  << " blocked=" << Named::getIDSecure(*blocked)
1948  << " gap=" << gap
1949  << "\n";
1950  }
1951 #endif
1952  if (gap > POSITION_EPS) {
1953  //const bool blockedWantsUrgentRight = (((*blocked)->getLaneChangeModel().getOwnState() & LCA_RIGHT != 0)
1954  // && ((*blocked)->getLaneChangeModel().getOwnState() & LCA_URGENT != 0));
1955 
1957  //|| blockedWantsUrgentRight // VARIANT_10 (helpblockedRight)
1958  ) {
1959  if ((*blocked)->getSpeed() < SUMO_const_haltingSpeed) {
1960  state |= LCA_AMBACKBLOCKER_STANDING;
1961  } else {
1962  state |= LCA_AMBACKBLOCKER;
1963  }
1966  (double)(gap - POSITION_EPS), (*blocked)->getSpeed(),
1967  (*blocked)->getCarFollowModel().getMaxDecel()));
1968 
1969  //(*blocked) = 0; // VARIANT_14 (furtherBlock)
1970 #ifdef DEBUG_SLOW_DOWN
1971  if (DEBUG_COND) {
1972  std::cout << SIMTIME
1973  << " veh=" << myVehicle.getID()
1974  << " slowing down for"
1975  << " blocked=" << Named::getIDSecure(*blocked)
1976  << " helpSpeed=" << myLCAccelerationAdvices.back()
1977  << "\n";
1978  }
1979 #endif
1980  } /* else {
1981  // experimental else-branch...
1982  state |= LCA_AMBACKBLOCKER;
1983  myVSafes.push_back(myCarFollowModel.followSpeed(
1984  &myVehicle, myVehicle.getSpeed(),
1985  (double)(gap - POSITION_EPS), (*blocked)->getSpeed(),
1986  (*blocked)->getCarFollowModel().getMaxDecel()));
1987  }*/
1988  }
1989  }
1990  return state;
1991 }
1992 
1993 
1994 void
1995 MSLCM_LC2013::saveBlockerLength(MSVehicle* blocker, int lcaCounter) {
1996 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1997  if (DEBUG_COND) {
1998  std::cout << SIMTIME
1999  << " veh=" << myVehicle.getID()
2000  << " saveBlockerLength blocker=" << Named::getIDSecure(blocker)
2001  << " bState=" << (blocker == 0 ? "None" : toString(blocker->getLaneChangeModel().getOwnState()))
2002  << "\n";
2003  }
2004 #endif
2005  if (blocker != nullptr && (blocker->getLaneChangeModel().getOwnState() & lcaCounter) != 0) {
2006  // is there enough space in front of us for the blocker?
2007  const double potential = myLeftSpace - myVehicle.getCarFollowModel().brakeGap(
2009  if (blocker->getVehicleType().getLengthWithGap() <= potential) {
2010  // save at least his length in myLeadingBlockerLength
2012 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
2013  if (DEBUG_COND) {
2014  std::cout << SIMTIME
2015  << " veh=" << myVehicle.getID()
2016  << " blocker=" << Named::getIDSecure(blocker)
2017  << " saving myLeadingBlockerLength=" << myLeadingBlockerLength
2018  << "\n";
2019  }
2020 #endif
2021  } else {
2022  // we cannot save enough space for the blocker. It needs to save
2023  // space for ego instead
2024 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
2025  if (DEBUG_COND) {
2026  std::cout << SIMTIME
2027  << " veh=" << myVehicle.getID()
2028  << " blocker=" << Named::getIDSecure(blocker)
2029  << " cannot save space=" << blocker->getVehicleType().getLengthWithGap()
2030  << " potential=" << potential
2031  << "\n";
2032  }
2033 #endif
2035  }
2036  }
2037 }
2038 
2039 
2040 void
2042  if (MSPModel::getModel()->hasPedestrians(lane)) {
2043 #ifdef DEBUG_WANTS_CHANGE
2044  if (DEBUG_COND) {
2045  std::cout << SIMTIME << " adapt to pedestrians on lane=" << lane->getID() << "\n";
2046  }
2047 #endif
2051  if (leader.first != 0) {
2052  const double stopSpeed = myVehicle.getCarFollowModel().stopSpeed(&myVehicle, myVehicle.getSpeed(), leader.second - myVehicle.getVehicleType().getMinGap());
2053  v = MIN2(v, stopSpeed);
2054 #ifdef DEBUG_WANTS_CHANGE
2055  if (DEBUG_COND) {
2056  std::cout << SIMTIME << " pedLeader=" << leader.first->getID() << " dist=" << leader.second << " v=" << v << "\n";
2057  }
2058 #endif
2059  }
2060  }
2061 }
2062 
2063 
2064 void MSLCM_LC2013::addLCSpeedAdvice(const double vSafe) {
2065  const double accel = SPEED2ACCEL(vSafe - myVehicle.getSpeed());
2066  myLCAccelerationAdvices.push_back(accel);
2067 }
2068 
2069 
2070 double
2071 MSLCM_LC2013::computeSpeedLat(double latDist, double& maneuverDist) {
2072  double speedBound = myMaxSpeedLatStanding + myMaxSpeedLatFactor * myVehicle.getSpeed();
2073  if (isChangingLanes()) {
2074  // Don't stay caught in the middle of a lane change while vehicle is standing, workaround for #3771
2075  speedBound = MAX2(LC_RESOLUTION_SPEED_LAT, speedBound);
2076  }
2077  return MAX2(-speedBound, MIN2(speedBound,
2078  MSAbstractLaneChangeModel::computeSpeedLat(latDist, maneuverDist)));
2079 }
2080 
2081 double
2084 }
2085 
2086 double
2088  return 1 / myAssertive;
2089 }
2090 
2091 double
2093  return myOppositeParam <= 0 ? std::numeric_limits<double>::max() : 1 / myOppositeParam;
2094 }
2095 
2096 std::string
2097 MSLCM_LC2013::getParameter(const std::string& key) const {
2099  return toString(myStrategicParam);
2100  } else if (key == toString(SUMO_ATTR_LCA_COOPERATIVE_PARAM)) {
2101  return toString(myCooperativeParam);
2102  } else if (key == toString(SUMO_ATTR_LCA_SPEEDGAIN_PARAM)) {
2103  return toString(mySpeedGainParam);
2104  } else if (key == toString(SUMO_ATTR_LCA_KEEPRIGHT_PARAM)) {
2105  return toString(myKeepRightParam);
2106  } else if (key == toString(SUMO_ATTR_LCA_OPPOSITE_PARAM)) {
2107  return toString(myOppositeParam);
2108  } else if (key == toString(SUMO_ATTR_LCA_LOOKAHEADLEFT)) {
2109  return toString(myLookaheadLeft);
2110  } else if (key == toString(SUMO_ATTR_LCA_SPEEDGAINRIGHT)) {
2111  return toString(mySpeedGainRight);
2112  } else if (key == toString(SUMO_ATTR_LCA_ASSERTIVE)) {
2113  return toString(myAssertive);
2114  } else if (key == toString(SUMO_ATTR_LCA_OVERTAKE_RIGHT)) {
2116  } else if (key == toString(SUMO_ATTR_LCA_SIGMA)) {
2117  return toString(mySigma);
2118  }
2119  throw InvalidArgument("Parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
2120 }
2121 
2122 
2123 void
2124 MSLCM_LC2013::setParameter(const std::string& key, const std::string& value) {
2125  double doubleValue;
2126  try {
2127  doubleValue = StringUtils::toDouble(value);
2128  } catch (NumberFormatException&) {
2129  throw InvalidArgument("Setting parameter '" + key + "' requires a number for laneChangeModel of type '" + toString(myModel) + "'");
2130  }
2132  myStrategicParam = doubleValue;
2133  } else if (key == toString(SUMO_ATTR_LCA_COOPERATIVE_PARAM)) {
2134  myCooperativeParam = doubleValue;
2135  } else if (key == toString(SUMO_ATTR_LCA_SPEEDGAIN_PARAM)) {
2136  mySpeedGainParam = doubleValue;
2137  } else if (key == toString(SUMO_ATTR_LCA_KEEPRIGHT_PARAM)) {
2138  myKeepRightParam = doubleValue;
2139  } else if (key == toString(SUMO_ATTR_LCA_OPPOSITE_PARAM)) {
2140  myOppositeParam = doubleValue;
2141  } else if (key == toString(SUMO_ATTR_LCA_LOOKAHEADLEFT)) {
2142  myLookaheadLeft = doubleValue;
2143  } else if (key == toString(SUMO_ATTR_LCA_SPEEDGAINRIGHT)) {
2144  mySpeedGainRight = doubleValue;
2145  } else if (key == toString(SUMO_ATTR_LCA_ASSERTIVE)) {
2146  myAssertive = doubleValue;
2147  } else if (key == toString(SUMO_ATTR_LCA_OVERTAKE_RIGHT)) {
2148  myOvertakeRightParam = doubleValue;
2149  } else if (key == toString(SUMO_ATTR_LCA_SIGMA)) {
2150  mySigma = doubleValue;
2151  } else {
2152  throw InvalidArgument("Setting parameter '" + key + "' is not supported for laneChangeModel of type '" + toString(myModel) + "'");
2153  }
2155 }
2156 
2157 /****************************************************************************/
2158 
MSLCM_LC2013::myStrategicParam
double myStrategicParam
Definition: MSLCM_LC2013.h:241
INVALID_SPEED
#define INVALID_SPEED
Definition: MSCFModel.h:32
URGENCY
#define URGENCY
Definition: MSLCM_LC2013.cpp:63
MSLCM_LC2013::getOppositeSafetyFactor
double getOppositeSafetyFactor() const
return factor for modifying the safety constraints for opposite-diretction overtaking of the car-foll...
Definition: MSLCM_LC2013.cpp:2092
MSLCM_LC2013::getAssumedDecelForLaneChangeDuration
double getAssumedDecelForLaneChangeDuration() const
Returns a deceleration value which is used for the estimation of the duration of a lane change.
Definition: MSLCM_LC2013.cpp:2082
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:31
MSEdge::isRoundabout
bool isRoundabout() const
Definition: MSEdge.h:640
SUMO_ATTR_LCA_SPEEDGAIN_PARAM
@ SUMO_ATTR_LCA_SPEEDGAIN_PARAM
Definition: SUMOXMLDefinitions.h:590
MSVehicle::LaneQ::bestLaneOffset
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive.
Definition: MSVehicle.h:822
LCA_MLEFT
@ LCA_MLEFT
Definition: SUMOXMLDefinitions.h:1289
MSVehicle::setLateralPositionOnLane
void setLateralPositionOnLane(double posLat)
Definition: MSVehicle.h:433
SPEED2DIST
#define SPEED2DIST(x)
Definition: SUMOTime.h:46
MSCFModel::brakeGap
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
Definition: MSCFModel.h:312
MSVehicle::getBestLaneOffset
int getBestLaneOffset() const
Definition: MSVehicle.cpp:5087
MSCFModel::getMaxAccel
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition: MSCFModel.h:209
OUProcess::step
void step(double dt)
evolve for a time step of length dt.
Definition: MSDriverState.cpp:105
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
MSCFModel::maximumSafeFollowSpeed
double maximumSafeFollowSpeed(double gap, double egoSpeed, double predSpeed, double predMaxDecel, bool onInsertion=false) const
Returns the maximum safe velocity for following the given leader.
Definition: MSCFModel.cpp:856
MSEdge::getPersons
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
Definition: MSEdge.h:176
MSAbstractLaneChangeModel::MSLCMessager::informNeighLeader
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
Definition: MSAbstractLaneChangeModel.h:83
MSCFModel::getMaxDecel
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:217
SVC_EMERGENCY
@ SVC_EMERGENCY
public emergency vehicles
Definition: SUMOVehicleClass.h:143
MSLCM_LC2013::addLCSpeedAdvice
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
Definition: MSLCM_LC2013.cpp:2064
REACT_TO_STOPPED_DISTANCE
#define REACT_TO_STOPPED_DISTANCE
Definition: MSLCM_LC2013.cpp:78
KEEP_RIGHT_TIME
#define KEEP_RIGHT_TIME
Definition: MSLCM_LC2013.cpp:66
MSLCM_LC2013::Info
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
Definition: MSLCM_LC2013.h:217
MSLCM_LC2013::myLookAheadSpeed
double myLookAheadSpeed
Definition: MSLCM_LC2013.h:231
MSNet.h
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSVehicle::isStopped
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1737
MSLCM_LC2013::myKeepRightProbability
double myKeepRightProbability
Definition: MSLCM_LC2013.h:224
LCA_LEFT
@ LCA_LEFT
Wants go to the left.
Definition: SUMOXMLDefinitions.h:1226
MSLCM_LC2013::getSafetyFactor
double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
Definition: MSLCM_LC2013.cpp:2087
MSAbstractLaneChangeModel::cancelRequest
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
Definition: MSAbstractLaneChangeModel.cpp:497
SUMO_ATTR_LCA_COOPERATIVE_PARAM
@ SUMO_ATTR_LCA_COOPERATIVE_PARAM
Definition: SUMOXMLDefinitions.h:589
MSLCM_LC2013::prepareStep
void prepareStep()
Definition: MSLCM_LC2013.cpp:1017
ROUNDABOUT_DIST_FACTOR
#define ROUNDABOUT_DIST_FACTOR
Definition: MSLCM_LC2013.cpp:69
MSAbstractLaneChangeModel::myAllowOvertakingRight
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
Definition: MSAbstractLaneChangeModel.h:707
MSJunction
The base class for an intersection.
Definition: MSJunction.h:60
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:36
MSVehicle::influenceChangeDecision
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:5924
MSLCM_LC2013::changed
void changed()
Definition: MSLCM_LC2013.cpp:1043
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:148
MSAbstractLaneChangeModel::MSLCMessager
A class responsible for exchanging messages between cars involved in lane-change interaction.
Definition: MSAbstractLaneChangeModel.h:51
StringUtils::toDouble
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
Definition: StringUtils.cpp:345
MSCFModel::gapExtrapolation
static double gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1=0, double a2=0, const double maxV1=std::numeric_limits< double >::max(), const double maxV2=std::numeric_limits< double >::max())
return the resulting gap if, starting with gap currentGap, two vehicles continue with constant accele...
Definition: MSCFModel.cpp:502
MSVehicle::LaneQ::length
double length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:814
ACCEL2SPEED
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:52
MSCFModel::getSecureGap
virtual double getSecureGap(const MSVehicle *const, const MSVehicle *const, const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:329
LCA_AMBLOCKINGLEADER
@ LCA_AMBLOCKINGLEADER
Definition: SUMOXMLDefinitions.h:1286
MSLane::isAccelLane
bool isAccelLane() const
return whether this lane is an acceleration lane
Definition: MSLane.h:487
SPEED2ACCEL
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:54
MSVehicle::LaneQ
A structure representing the best lanes for continuing the current route starting at 'lane'.
Definition: MSVehicle.h:810
MSLCM_LC2013::_wantsChange
int _wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
helper function for doing the actual work
Definition: MSLCM_LC2013.cpp:1060
MSLCM_LC2013::getRoundaboutDistBonus
double getRoundaboutDistBonus(const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, const MSVehicle::LaneQ &best)
Computes the artificial bonus distance for roundabout lanes this additional distance reduces the sens...
Definition: MSLCM_LC2013.cpp:1787
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:34
LOOK_FORWARD
#define LOOK_FORWARD
Definition: MSLCM_LC2013.cpp:44
MSLCM_LC2013::patchSpeed
double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
Called to adapt the speed in order to allow a lane change. It uses information on LC-related desired ...
Definition: MSLCM_LC2013.cpp:188
LCA_SPEEDGAIN
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
Definition: SUMOXMLDefinitions.h:1234
LCA_URGENT
@ LCA_URGENT
The action is urgent (to be defined by lc-model)
Definition: SUMOXMLDefinitions.h:1240
MSLCM_LC2013::saveBlockerLength
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
Definition: MSLCM_LC2013.cpp:1995
LCA_BLOCKED_BY_LEADER
@ LCA_BLOCKED_BY_LEADER
blocked by leader
Definition: SUMOXMLDefinitions.h:1272
MSEdge.h
MSLCM_LC2013::myChangeProbThresholdLeft
double myChangeProbThresholdLeft
Definition: MSLCM_LC2013.h:266
JAM_FACTOR
#define JAM_FACTOR
Definition: MSLCM_LC2013.cpp:46
MSEdge::hasLaneChanger
bool hasLaneChanger() const
Definition: MSEdge.h:657
RELGAIN_NORMALIZATION_MIN_SPEED
#define RELGAIN_NORMALIZATION_MIN_SPEED
Definition: MSLCM_LC2013.cpp:62
SUMO_ATTR_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_LCA_KEEPRIGHT_PARAM
Definition: SUMOXMLDefinitions.h:591
MSVehicle::getNextStop
Stop & getNextStop()
Definition: MSVehicle.cpp:5890
TURN_LANE_DIST
#define TURN_LANE_DIST
Definition: MSLCM_LC2013.cpp:73
MSVehicle::getCarFollowModel
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:893
MSLane::getBruttoOccupancy
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2677
MSLCM_LC2013::mySpeedGainParam
double mySpeedGainParam
Definition: MSLCM_LC2013.h:243
MSLCM_LC2013::myAssertive
double myAssertive
Definition: MSLCM_LC2013.h:253
MSAbstractLaneChangeModel::isChangingLanes
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
Definition: MSAbstractLaneChangeModel.h:441
SUMO_ATTR_LCA_EXPERIMENTAL1
@ SUMO_ATTR_LCA_EXPERIMENTAL1
Definition: SUMOXMLDefinitions.h:608
MSJunction::getIncoming
const ConstMSEdgeVector & getIncoming() const
Definition: MSJunction.h:101
SUMO_const_haltingSpeed
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:60
MSLCM_LC2013::wantsChange
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
Called to examine whether the vehicle wants to change using the given laneOffset. This method gets th...
Definition: MSLCM_LC2013.cpp:149
MSJunction::getOutgoing
const ConstMSEdgeVector & getOutgoing() const
Definition: MSJunction.h:107
MSLCM_LC2013::myKeepRightParam
double myKeepRightParam
Definition: MSLCM_LC2013.h:244
MSVehicle::getLateralPositionOnLane
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:429
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
MSEdge::isInternal
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:235
MSLane::getBruttoVehLenSum
double getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:1004
MSLCM_LC2013::currentDistAllows
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
Definition: MSLCM_LC2013.h:202
NumberFormatException
Definition: UtilExceptions.h:95
MSLCM_LC2013::debugVehicle
bool debugVehicle() const
whether the current vehicles shall be debugged
Definition: MSLCM_LC2013.cpp:143
LCA_RIGHT_IMPATIENCE
#define LCA_RIGHT_IMPATIENCE
Definition: MSLCM_LC2013.cpp:48
MSLCM_LC2013::computeSpeedLat
double computeSpeedLat(double latDist, double &maneuverDist)
decides the next lateral speed (for continuous lane changing)
Definition: MSLCM_LC2013.cpp:2071
MSLCM_LC2013::overtakeDistance
static double overtakeDistance(const MSVehicle *follower, const MSVehicle *leader, const double gap, double followerSpeed=INVALID_SPEED, double leaderSpeed=INVALID_SPEED)
Definition: MSLCM_LC2013.cpp:431
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:63
MSLCM_LC2013.h
PersonDist
std::pair< const MSPerson *, double > PersonDist
Definition: MSPModel.h:40
LCA_STRATEGIC
@ LCA_STRATEGIC
The action is needed to follow the route (navigational lc)
Definition: SUMOXMLDefinitions.h:1230
MSVehicle::getPositionOnLane
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:392
MSAbstractLaneChangeModel::getCanceledState
int & getCanceledState(const int dir)
Definition: MSAbstractLaneChangeModel.h:232
MSLCM_LC2013::mySpeedGainProbability
double mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial
Definition: MSLCM_LC2013.h:220
MSLCM_LC2013::informFollower
void informFollower(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighFollow, double remainingSeconds, double plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
Definition: MSLCM_LC2013.cpp:616
MSBaseVehicle::getImpatience
double getImpatience() const
Returns this vehicles impatience.
Definition: MSBaseVehicle.cpp:557
MSLCM_LC2013::slowDownForBlocked
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
Definition: MSLCM_LC2013.cpp:1939
MSVehicle::getActionStepLengthSecs
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points.
Definition: MSVehicle.h:512
LaneChangeAction
LaneChangeAction
The state of a vehicle's lane-change behavior.
Definition: SUMOXMLDefinitions.h:1218
MSVehicleType::getWidth
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
Definition: MSVehicleType.h:246
OPPOSITE_URGENCY
#define OPPOSITE_URGENCY
Definition: MSLCM_LC2013.cpp:64
LOOK_AHEAD_SPEED_MEMORY
#define LOOK_AHEAD_SPEED_MEMORY
Definition: MSLCM_LC2013.cpp:52
SUMO_ATTR_LCA_OPPOSITE_PARAM
@ SUMO_ATTR_LCA_OPPOSITE_PARAM
Definition: SUMOXMLDefinitions.h:593
MSLCM_LC2013::initDerivedParameters
void initDerivedParameters()
init cached parameters derived directly from model parameters
Definition: MSLCM_LC2013.cpp:136
MSAbstractLaneChangeModel::myMaxSpeedLatFactor
double myMaxSpeedLatFactor
Definition: MSAbstractLaneChangeModel.h:698
MSVehicleType::getLengthWithGap
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
Definition: MSVehicleType.h:117
TS
#define TS
Definition: SUMOTime.h:43
MSLCM_LC2013::currentDistDisallows
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
Definition: MSLCM_LC2013.h:199
MSAbstractLaneChangeModel::prepareStep
virtual void prepareStep()
Definition: MSAbstractLaneChangeModel.cpp:889
MSAbstractLaneChangeModel::myModel
const LaneChangeModel myModel
the type of this model
Definition: MSAbstractLaneChangeModel.h:664
MSLCM_LC2013::_patchSpeed
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
Definition: MSLCM_LC2013.cpp:221
MSLCM_LC2013::myChangeProbThresholdRight
double myChangeProbThresholdRight
Definition: MSLCM_LC2013.h:265
LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
@ LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
Definition: SUMOXMLDefinitions.h:1291
MSNet::getCurrentTimeStep
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:283
MSCFModel::maximumSafeStopSpeed
double maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:711
STEPS2TIME
#define STEPS2TIME(x)
Definition: SUMOTime.h:56
SUMO_ATTR_LCA_SPEEDGAINRIGHT
@ SUMO_ATTR_LCA_SPEEDGAINRIGHT
Definition: SUMOXMLDefinitions.h:601
MSLane::getLength
double getLength() const
Returns the lane's length.
Definition: MSLane.h:540
DEBUG_COND
#define DEBUG_COND
Definition: MSLCM_LC2013.cpp:93
MSLCM_LC2013::adaptSpeedToPedestrians
void adaptSpeedToPedestrians(const MSLane *lane, double &v)
react to pedestrians on the given lane
Definition: MSLCM_LC2013.cpp:2041
MSLCM_LC2013::myLCAccelerationAdvices
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()
Definition: MSLCM_LC2013.h:235
MSLane::getOppositePos
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:3527
MSVehicle::getLaneChangeModel
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:4680
MSAbstractLaneChangeModel::isOpposite
bool isOpposite() const
Definition: MSAbstractLaneChangeModel.h:535
SUMO_ATTR_LCA_LOOKAHEADLEFT
@ SUMO_ATTR_LCA_LOOKAHEADLEFT
Definition: SUMOXMLDefinitions.h:600
MSVehicle::LaneQ::lane
MSLane * lane
The described lane.
Definition: MSVehicle.h:812
SUMO_ATTR_LCA_OVERTAKE_RIGHT
@ SUMO_ATTR_LCA_OVERTAKE_RIGHT
Definition: SUMOXMLDefinitions.h:605
MSVehicle::Stop::lane
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:926
SUMO_ATTR_LCA_STRATEGIC_PARAM
@ SUMO_ATTR_LCA_STRATEGIC_PARAM
Definition: SUMOXMLDefinitions.h:588
MSVehicleType::getMinGap
double getMinGap() const
Get the free space in front of vehicles of this class.
Definition: MSVehicleType.h:125
MSVehicle::LaneQ::occupation
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:818
MSAbstractLaneChangeModel::MSLCMessager::informNeighFollower
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
Definition: MSAbstractLaneChangeModel.h:94
MSEdge::getToJunction
const MSJunction * getToJunction() const
Definition: MSEdge.h:363
MSVehicle::getLastStepDist
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
Definition: MSVehicle.h:399
MSLCM_LC2013::myCooperativeParam
double myCooperativeParam
Definition: MSLCM_LC2013.h:242
HELP_OVERTAKE
#define HELP_OVERTAKE
Definition: MSLCM_LC2013.cpp:56
MSBaseVehicle::getVehicleType
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:123
MSLCM_LC2013::~MSLCM_LC2013
virtual ~MSLCM_LC2013()
Definition: MSLCM_LC2013.cpp:130
MSLane::getLinkCont
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:2110
MSLCM_LC2013::myDontBrake
bool myDontBrake
Definition: MSLCM_LC2013.h:237
MSLCM_LC2013::mySpeedGainRight
double mySpeedGainRight
Definition: MSLCM_LC2013.h:250
LCA_WANTS_LANECHANGE
@ LCA_WANTS_LANECHANGE
lane can change
Definition: SUMOXMLDefinitions.h:1264
MSLCM_LC2013::myOppositeParam
double myOppositeParam
Definition: MSLCM_LC2013.h:245
SUMO_ATTR_LCA_ASSERTIVE
@ SUMO_ATTR_LCA_ASSERTIVE
Definition: SUMOXMLDefinitions.h:596
MSLCM_LC2013::myExperimentalParam1
const double myExperimentalParam1
Definition: MSLCM_LC2013.h:258
MSPModel::nextBlocking
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0
Definition: MSPModel.h:93
MSVehicle::getLane
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:560
MSLane::getEdge
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:669
CUT_IN_LEFT_SPEED_THRESHOLD
#define CUT_IN_LEFT_SPEED_THRESHOLD
Definition: MSLCM_LC2013.cpp:49
MSVehicle::getInfluencer
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:5900
HELP_DECEL_FACTOR
#define HELP_DECEL_FACTOR
Definition: MSLCM_LC2013.cpp:54
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
MSAbstractLaneChangeModel::myMaxSpeedLatStanding
double myMaxSpeedLatStanding
Definition: MSAbstractLaneChangeModel.h:696
StringUtils.h
LCA_RIGHT
@ LCA_RIGHT
Wants go to the right.
Definition: SUMOXMLDefinitions.h:1228
MSVehicle::LaneQ::bestContinuations
std::vector< MSLane * > bestContinuations
Definition: MSVehicle.h:830
MSDriverState.h
MSVehicle::congested
bool congested() const
Definition: MSVehicle.h:717
MSCFModel::minNextSpeed
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
Definition: MSCFModel.cpp:244
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
MSAbstractLaneChangeModel::myCarFollowModel
const MSCFModel & myCarFollowModel
The vehicle's car following model.
Definition: MSAbstractLaneChangeModel.h:661
LCA_STAY
@ LCA_STAY
Needs to stay on the current lane.
Definition: SUMOXMLDefinitions.h:1224
MSCFModel::getSpeedAfterMaxDecel
virtual double getSpeedAfterMaxDecel(double v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:342
MSAbstractLaneChangeModel::saveBlockerLength
virtual void saveBlockerLength(double length)
reserve space at the end of the lane to avoid dead locks
Definition: MSAbstractLaneChangeModel.h:507
LCA_AMBACKBLOCKER_STANDING
@ LCA_AMBACKBLOCKER_STANDING
Definition: SUMOXMLDefinitions.h:1297
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:109
InvalidArgument
Definition: UtilExceptions.h:56
MSCFModel::stopSpeed
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
MSAbstractLaneChangeModel::myOwnState
int myOwnState
The current state of the vehicle.
Definition: MSAbstractLaneChangeModel.h:592
MSVehicle::getRightSideOnLane
double getRightSideOnLane() const
Get the vehicle's lateral position on the lane:
Definition: MSVehicle.cpp:5321
MSPModel.h
LOOK_AHEAD_MIN_SPEED
#define LOOK_AHEAD_MIN_SPEED
Definition: MSLCM_LC2013.cpp:51
MSBaseVehicle::getID
const std::string & getID() const
Returns the name of the vehicle.
Definition: MSBaseVehicle.cpp:138
MSLCM_LC2013::myLeftSpace
double myLeftSpace
Definition: MSLCM_LC2013.h:227
MSLCM_LC2013::myLookaheadLeft
double myLookaheadLeft
Definition: MSLCM_LC2013.h:248
MSVehicle::getAcceleration
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Definition: MSVehicle.h:493
MSPModel::getModel
static MSPModel * getModel()
Definition: MSPModel.cpp:63
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:56
LC_ASSUMED_DECEL
#define LC_ASSUMED_DECEL
Definition: MSLCM_LC2013.cpp:76
MSLCM_LC2013::getParameter
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
Definition: MSLCM_LC2013.cpp:2097
MSAbstractLaneChangeModel::getOwnState
int getOwnState() const
Definition: MSAbstractLaneChangeModel.h:174
config.h
LCA_BLOCKED_BY_FOLLOWER
@ LCA_BLOCKED_BY_FOLLOWER
blocker by follower
Definition: SUMOXMLDefinitions.h:1274
MSLCM_LC2013::myOvertakeRightParam
double myOvertakeRightParam
Definition: MSLCM_LC2013.h:255
Named::getIDSecure
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:69
MSAbstractLaneChangeModel
Interface for lane-change models.
Definition: MSAbstractLaneChangeModel.h:45
MSVehicle::getSpeed
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:476
MSAbstractLaneChangeModel::myVehicle
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
Definition: MSAbstractLaneChangeModel.h:589
RandHelper.h
LCA_KEEPRIGHT
@ LCA_KEEPRIGHT
The action is due to the default of keeping right "Rechtsfahrgebot".
Definition: SUMOXMLDefinitions.h:1236
gPrecision
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:26
MSGlobals::gLaneChangeDuration
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:81
MSLane.h
MSAbstractLaneChangeModel::computeSpeedLat
virtual double computeSpeedLat(double latDist, double &maneuverDist)
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
Definition: MSAbstractLaneChangeModel.cpp:373
MAX_ONRAMP_LENGTH
#define MAX_ONRAMP_LENGTH
Definition: MSLCM_LC2013.cpp:72
MSLane::getVehicleMaxSpeed
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:518
MSVehicle::Influencer::changeRequestRemainingSeconds
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:749
LCA_AMBACKBLOCKER
@ LCA_AMBACKBLOCKER
Definition: SUMOXMLDefinitions.h:1296
MSLane::getSpeedLimit
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:532
MSVehicleType::getVehicleClass
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
Definition: MSVehicleType.h:184
MSLCM_LC2013::inform
void * inform(void *info, MSVehicle *sender)
Definition: MSLCM_LC2013.cpp:410
MSGlobals::gSemiImplicitEulerUpdate
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:55
LCA_MRIGHT
@ LCA_MRIGHT
Definition: SUMOXMLDefinitions.h:1288
MSVehicle::nextStopDist
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
Definition: MSVehicle.h:1052
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
SUMO_ATTR_LCA_SIGMA
@ SUMO_ATTR_LCA_SIGMA
Definition: SUMOXMLDefinitions.h:607
MSCFModel::followSpeed
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle's follow speed (no dawdling)
LCA_COOPERATIVE
@ LCA_COOPERATIVE
The action is done to help someone else.
Definition: SUMOXMLDefinitions.h:1232
KEEP_RIGHT_ACCEPTANCE
#define KEEP_RIGHT_ACCEPTANCE
Definition: MSLCM_LC2013.cpp:67
MSLCM_LC2013::setParameter
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
Definition: MSLCM_LC2013.cpp:2124
MSLCM_LC2013::amBlockingFollowerPlusNB
bool amBlockingFollowerPlusNB()
Definition: MSLCM_LC2013.h:196
MIN_FALLBEHIND
#define MIN_FALLBEHIND
Definition: MSLCM_LC2013.cpp:57
LCA_AMBLOCKINGFOLLOWER
@ LCA_AMBLOCKINGFOLLOWER
Definition: SUMOXMLDefinitions.h:1287
LCA_TRACI
@ LCA_TRACI
The action is due to a TraCI request.
Definition: SUMOXMLDefinitions.h:1238
LCM_LC2013
@ LCM_LC2013
Definition: SUMOXMLDefinitions.h:1305
LCA_BLOCKED
@ LCA_BLOCKED
blocked in all directions
Definition: SUMOXMLDefinitions.h:1276
MSVehicle::getWaitingSeconds
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:656
MSAbstractLaneChangeModel::mySigma
double mySigma
Definition: MSAbstractLaneChangeModel.h:700
MSLCM_LC2013::informLeader
double informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighLead, double remainingSeconds)
Definition: MSLCM_LC2013.cpp:444
MSBaseVehicle::getRNG
std::mt19937 * getRNG() const
Definition: MSBaseVehicle.cpp:758
MSLCM_LC2013::myLeadingBlockerLength
double myLeadingBlockerLength
Definition: MSLCM_LC2013.h:226
MSLCM_LC2013::MSLCM_LC2013
MSLCM_LC2013(MSVehicle &v)
Definition: MSLCM_LC2013.cpp:99
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
MSVehicle::getMaxSpeedOnLane
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation,...
Definition: MSVehicle.h:570
LC_RESOLUTION_SPEED_LAT
#define LC_RESOLUTION_SPEED_LAT
Definition: MSLCM_LC2013.cpp:75