SUMO - Simulation of Urban MObility
MSLCM_JE2013.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // A lane change model developed by J. Erdmann
10 // based on the model of D. Krajzewicz developed between 2004 and 2011 (MSLCM_DK2004)
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2013-2016 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <iostream>
36 #include <microsim/MSEdge.h>
37 #include <microsim/MSLane.h>
38 #include <microsim/MSNet.h>
39 #include "MSLCM_JE2013.h"
40 
41 #ifdef CHECK_MEMORY_LEAKS
42 #include <foreign/nvwa/debug_new.h>
43 #endif // CHECK_MEMORY_LEAKS
44 
45 
46 // ===========================================================================
47 // variable definitions
48 // ===========================================================================
49 // 80km/h will be the threshold for dividing between long/short foresight
50 #define LOOK_FORWARD_SPEED_DIVIDER (SUMOReal)14.
51 
52 #define LOOK_FORWARD_RIGHT (SUMOReal)10.
53 #define LOOK_FORWARD_LEFT (SUMOReal)20.
54 
55 #define JAM_FACTOR (SUMOReal)1.
56 
57 #define LCA_RIGHT_IMPATIENCE (SUMOReal)-1.
58 #define CUT_IN_LEFT_SPEED_THRESHOLD (SUMOReal)27.
59 
60 #define LOOK_AHEAD_MIN_SPEED (SUMOReal)0.0
61 #define LOOK_AHEAD_SPEED_MEMORY (SUMOReal)0.9
62 #define LOOK_AHEAD_SPEED_DECREMENT 6.
63 
64 #define HELP_DECEL_FACTOR (SUMOReal)1.0
65 
66 #define HELP_OVERTAKE (SUMOReal)(10.0 / 3.6)
67 #define MIN_FALLBEHIND (SUMOReal)(7.0 / 3.6)
68 
69 #define RELGAIN_NORMALIZATION_MIN_SPEED (SUMOReal)10.0
70 #define URGENCY (SUMOReal)2.0
71 
72 #define KEEP_RIGHT_TIME (SUMOReal)5.0 // the number of seconds after which a vehicle should move to the right lane
73 #define KEEP_RIGHT_ACCEPTANCE (SUMOReal)7.0 // calibration factor for determining the desire to keep right
74 #define ROUNDABOUT_DIST_BONUS (SUMOReal)100.0
75 
76 
77 #define KEEP_RIGHT_HEADWAY (SUMOReal)2.0
78 #define MAX_ONRAMP_LENGTH (SUMOReal)200.
79 #define TURN_LANE_DIST (SUMOReal)200.0 // the distance at which a lane leading elsewhere is considered to be a turn-lane that must be avoided
80 
81 // ===========================================================================
82 // debug defines
83 // ===========================================================================
84 //#define DEBUG_PATCH_SPEED
85 //#define DEBUG_INFORMED
86 //#define DEBUG_INFORMER
87 //#define DEBUG_CONSTRUCTOR
88 //#define DEBUG_WANTS_CHANGE
89 //#define DEBUG_SLOW_DOWN
90 //#define DEBUG_SAVE_BLOCKER_LENGTH
91 
92 #define DEBUG_COND (myVehicle.getID() == "disabled")
93 
94 // ===========================================================================
95 // member method definitions
96 // ===========================================================================
99  mySpeedGainProbability(0),
100  myKeepRightProbability(0),
101  myLeadingBlockerLength(0),
102  myLeftSpace(0),
103  myLookAheadSpeed(LOOK_AHEAD_MIN_SPEED),
104  myStrategicParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_STRATEGIC_PARAM, 1)),
105  myCooperativeParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_COOPERATIVE_PARAM, 1)),
106  mySpeedGainParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_SPEEDGAIN_PARAM, 1)),
107  myKeepRightParam(v.getVehicleType().getParameter().getLCParam(SUMO_ATTR_LCA_KEEPRIGHT_PARAM, 1)),
108  myChangeProbThresholdRight(2.0 * myKeepRightParam / MAX2(NUMERICAL_EPS, mySpeedGainParam)),
109  myChangeProbThresholdLeft(0.2 / MAX2(NUMERICAL_EPS, mySpeedGainParam)) {
110 #ifdef DEBUG_CONSTRUCTOR
111  if (DEBUG_COND) {
112  std::cout << SIMTIME
113  << " create lcModel veh=" << myVehicle.getID()
114  << " lcStrategic=" << myStrategicParam
115  << " lcCooperative=" << myCooperativeParam
116  << " lcSpeedGain=" << mySpeedGainParam
117  << " lcKeepRight=" << myKeepRightParam
118  << "\n";
119  }
120 #endif
121 }
122 
124  changed();
125 }
126 
127 
128 bool
130  return DEBUG_COND;
131 }
132 
133 
134 int
136  int laneOffset,
138  int blocked,
139  const std::pair<MSVehicle*, SUMOReal>& leader,
140  const std::pair<MSVehicle*, SUMOReal>& neighLead,
141  const std::pair<MSVehicle*, SUMOReal>& neighFollow,
142  const MSLane& neighLane,
143  const std::vector<MSVehicle::LaneQ>& preb,
144  MSVehicle** lastBlocked,
145  MSVehicle** firstBlocked) {
146 
147 #ifdef DEBUG_WANTS_CHANGE
148  if (DEBUG_COND) {
149  std::cout << "\n" << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
150  //<< std::setprecision(10)
151  << " veh=" << myVehicle.getID()
152  << " lane=" << myVehicle.getLane()->getID()
153  << " pos=" << myVehicle.getPositionOnLane()
154  << " posLat=" << myVehicle.getLateralPositionOnLane()
155  << " speed=" << myVehicle.getSpeed()
156  << " considerChangeTo=" << (laneOffset == -1 ? "right" : "left")
157  << "\n";
158  }
159 #endif
160 
161  const int result = _wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
162 
163 #ifdef DEBUG_WANTS_CHANGE
164  if (DEBUG_COND) {
165  if (result & LCA_WANTS_LANECHANGE) {
166  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
167  << " veh=" << myVehicle.getID()
168  << " wantsChangeTo=" << (laneOffset == -1 ? "right" : "left")
169  << ((result & LCA_URGENT) ? " (urgent)" : "")
170  << ((result & LCA_CHANGE_TO_HELP) ? " (toHelp)" : "")
171  << ((result & LCA_STRATEGIC) ? " (strat)" : "")
172  << ((result & LCA_COOPERATIVE) ? " (coop)" : "")
173  << ((result & LCA_SPEEDGAIN) ? " (speed)" : "")
174  << ((result & LCA_KEEPRIGHT) ? " (keepright)" : "")
175  << ((result & LCA_TRACI) ? " (traci)" : "")
176  << ((blocked & LCA_BLOCKED) ? " (blocked)" : "")
177  << ((blocked & LCA_OVERLAPPING) ? " (overlap)" : "")
178  << "\n\n\n";
179  }
180  }
181 #endif
182 
183  return result;
184 }
185 
186 
187 SUMOReal
188 MSLCM_JE2013::patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel& cfModel) {
189  const SUMOReal newSpeed = _patchSpeed(min, wanted, max, cfModel);
190 
191 #ifdef DEBUG_PATCH_SPEED
192  if (DEBUG_COND) {
193  const std::string patched = (wanted != newSpeed ? " patched=" + toString(newSpeed) : "");
194  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
195  << " veh=" << myVehicle.getID()
196  << " lane=" << myVehicle.getLane()->getID()
197  << " pos=" << myVehicle.getPositionOnLane()
198  << " v=" << myVehicle.getSpeed()
199  << " wanted=" << wanted
200  << patched
201  << "\n\n";
202  }
203 #endif
204 
205  return newSpeed;
206 }
207 
208 
209 SUMOReal
210 MSLCM_JE2013::_patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel& cfModel) {
211  int state = myOwnState;
212 #ifdef DEBUG_PATCH_SPEED
213  if (DEBUG_COND) {
214  std::cout << SIMTIME << " patchSpeed state=" << state << " myVSafes=" << toString(myVSafes) << "\n";
215  }
216 #endif
217  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#2
218  SUMOReal MAGIC_offset = 1.;
219  // if we want to change and have a blocking leader and there is enough room for him in front of us
220  if (myLeadingBlockerLength != 0) {
222 #ifdef DEBUG_PATCH_SPEED
223  if (DEBUG_COND) {
224  std::cout << SIMTIME << " veh=" << myVehicle.getID() << " myLeadingBlockerLength=" << myLeadingBlockerLength << " space=" << space << "\n";
225  }
226 #endif
227  if (space > 0) { // XXX space > -MAGIC_offset
228  // compute speed for decelerating towards a place which allows the blocking leader to merge in in front
229  SUMOReal safe = cfModel.stopSpeed(&myVehicle, myVehicle.getSpeed(), space);
230  // if we are approaching this place
231  if (safe < wanted) {
232  // return this speed as the speed to use
233 #ifdef DEBUG_PATCH_SPEED
234  if (DEBUG_COND) {
235  std::cout << time << " veh=" << myVehicle.getID() << " slowing down for leading blocker, safe=" << safe << (safe + NUMERICAL_EPS < min ? " (not enough)" : "") << "\n";
236  }
237 #endif
238  return MAX2(min, safe);
239  }
240  }
241  }
242 
243  SUMOReal nVSafe = wanted;
244  bool gotOne = false;
245  for (std::vector<SUMOReal>::const_iterator i = myVSafes.begin(); i != myVSafes.end(); ++i) {
246  SUMOReal v = (*i);
247  if (v >= min && v <= max) {
248  nVSafe = MIN2(v * myCooperativeParam + (1 - myCooperativeParam) * wanted, nVSafe);
249  gotOne = true;
250 #ifdef DEBUG_PATCH_SPEED
251  if (DEBUG_COND) {
252  std::cout << time << " veh=" << myVehicle.getID() << " got nVSafe=" << nVSafe << "\n";
253  }
254 #endif
255  } else {
256  if (v < min) {
257 #ifdef DEBUG_PATCH_SPEED
258  if (DEBUG_COND) {
259  std::cout << time << " veh=" << myVehicle.getID() << " ignoring low nVSafe=" << v << " min=" << min << "\n";
260  }
261 #endif
262  } else {
263 #ifdef DEBUG_PATCH_SPEED
264  if (DEBUG_COND) {
265  std::cout << time << " veh=" << myVehicle.getID() << " ignoring high nVSafe=" << v << " max=" << max << "\n";
266  }
267 #endif
268  }
269  }
270  }
271 
272  if (gotOne && !myDontBrake) {
273 #ifdef DEBUG_PATCH_SPEED
274  if (DEBUG_COND) {
275  std::cout << time << " veh=" << myVehicle.getID() << " got vSafe\n";
276  }
277 #endif
278  return nVSafe;
279  }
280 
281  // check whether the vehicle is blocked
282  if ((state & LCA_WANTS_LANECHANGE) != 0 && (state & LCA_BLOCKED) != 0) {
283  if ((state & LCA_STRATEGIC) != 0) {
284  // necessary decelerations are controlled via vSafe. If there are
285  // none it means we should speed up
286 #ifdef DEBUG_PATCH_SPEED
287  if (DEBUG_COND) {
288  std::cout << time << " veh=" << myVehicle.getID() << " LCA_WANTS_LANECHANGE (strat, no vSafe)\n";
289  }
290 #endif
291  return (max + wanted) / (SUMOReal) 2.0;
292  } else if ((state & LCA_COOPERATIVE) != 0) {
293  // only minor adjustments in speed should be done
294  if ((state & LCA_BLOCKED_BY_LEADER) != 0) {
295 #ifdef DEBUG_PATCH_SPEED
296  if (DEBUG_COND) {
297  std::cout << time << " veh=" << myVehicle.getID() << " LCA_BLOCKED_BY_LEADER (coop)\n";
298  }
299 #endif
300  return (min + wanted) / (SUMOReal) 2.0;
301  }
302  if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) {
303 #ifdef DEBUG_PATCH_SPEED
304  if (DEBUG_COND) {
305  std::cout << time << " veh=" << myVehicle.getID() << " LCA_BLOCKED_BY_FOLLOWER (coop)\n";
306  }
307 #endif
308  return (max + wanted) / (SUMOReal) 2.0;
309  }
310  //} else { // VARIANT_16
311  // // only accelerations should be performed
312  // if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) {
313  // if (gDebugFlag2) std::cout << time << " veh=" << myVehicle.getID() << " LCA_BLOCKED_BY_FOLLOWER\n";
314  // return (max + wanted) / (SUMOReal) 2.0;
315  // }
316  }
317  }
318 
319  /*
320  // decelerate if being a blocking follower
321  // (and does not have to change lanes)
322  if ((state & LCA_AMBLOCKINGFOLLOWER) != 0) {
323  if (fabs(max - myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle)) < 0.001 && min == 0) { // !!! was standing
324  if (gDebugFlag2) std::cout << time << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGFOLLOWER (standing)\n";
325  return 0;
326  }
327  if (gDebugFlag2) std::cout << time << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGFOLLOWER\n";
328 
329  //return min; // VARIANT_3 (brakeStrong)
330  return (min + wanted) / (SUMOReal) 2.0;
331  }
332  if ((state & LCA_AMBACKBLOCKER) != 0) {
333  if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle) && min == 0) { // !!! was standing
334  if (gDebugFlag2) std::cout << time << " veh=" << myVehicle.getID() << " LCA_AMBACKBLOCKER (standing)\n";
335  //return min; VARIANT_9 (backBlockVSafe)
336  return nVSafe;
337  }
338  }
339  if ((state & LCA_AMBACKBLOCKER_STANDING) != 0) {
340  if (gDebugFlag2) std::cout << time << " veh=" << myVehicle.getID() << " LCA_AMBACKBLOCKER_STANDING\n";
341  //return min;
342  return nVSafe;
343  }
344  */
345 
346  // accelerate if being a blocking leader or blocking follower not able to brake
347  // (and does not have to change lanes)
348  if ((state & LCA_AMBLOCKINGLEADER) != 0) {
349 #ifdef DEBUG_PATCH_SPEED
350  if (DEBUG_COND) {
351  std::cout << time << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGLEADER\n";
352  }
353 #endif
354  return (max + wanted) / (SUMOReal) 2.0;
355  }
356 
357  if ((state & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) {
358 #ifdef DEBUG_PATCH_SPEED
359  if (DEBUG_COND) {
360  std::cout << time << " veh=" << myVehicle.getID() << " LCA_AMBLOCKINGFOLLOWER_DONTBRAKE\n";
361  }
362 #endif
363  /*
364  // VARIANT_4 (dontbrake)
365  if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle) && min == 0) { // !!! was standing
366  return wanted;
367  }
368  return (min + wanted) / (SUMOReal) 2.0;
369  */
370  }
371  if (!myVehicle.getLane()->getEdge().hasLaneChanger()) {
372  // remove chaning information if on a road with a single lane
373  changed();
374  }
375  return wanted;
376 }
377 
378 
379 void*
380 MSLCM_JE2013::inform(void* info, MSVehicle* sender) {
381  UNUSED_PARAMETER(sender);
382  Info* pinfo = (Info*) info;
383  if (pinfo->first >= 0) {
384  myVSafes.push_back(pinfo->first);
385  }
386  //myOwnState &= 0xffffffff; // reset all bits of MyLCAEnum but only those
387  myOwnState |= pinfo->second;
388 #ifdef DEBUG_INFORMED
389  if (DEBUG_COND) {
390  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
391  << " veh=" << myVehicle.getID()
392  << " informedBy=" << sender->getID()
393  << " info=" << pinfo->second
394  << " vSafe=" << pinfo->first
395  << "\n";
396  }
397 #endif
398  delete pinfo;
399  return (void*) true;
400 }
401 
402 
403 SUMOReal
405  int blocked,
406  int dir,
407  const std::pair<MSVehicle*, SUMOReal>& neighLead,
408  SUMOReal remainingSeconds) {
409  SUMOReal plannedSpeed = MIN2(myVehicle.getSpeed(),
411  for (std::vector<SUMOReal>::const_iterator i = myVSafes.begin(); i != myVSafes.end(); ++i) {
412  SUMOReal v = (*i);
414  plannedSpeed = MIN2(plannedSpeed, v);
415  }
416  }
417 #ifdef DEBUG_INFORMER
418  if (DEBUG_COND) {
419  std::cout << " informLeader speed=" << myVehicle.getSpeed() << " planned=" << plannedSpeed << "\n";
420  }
421 #endif
422 
423  if ((blocked & LCA_BLOCKED_BY_LEADER) != 0) {
424  assert(neighLead.first != 0);
425  MSVehicle* nv = neighLead.first;
426 #ifdef DEBUG_INFORMER
427  if (DEBUG_COND) {
428  std::cout << " blocked by leader nv=" << nv->getID() << " nvSpeed=" << nv->getSpeed() << " needGap="
430  }
431 #endif
432  // decide whether we want to overtake the leader or follow it
433  const SUMOReal dv = plannedSpeed - nv->getSpeed();
434  const SUMOReal overtakeDist = (neighLead.second // drive to back of follower
435  + nv->getVehicleType().getLengthWithGap() // drive to front of follower
436  + myVehicle.getVehicleType().getLength() // ego back reaches follower front
437  + nv->getCarFollowModel().getSecureGap( // save gap to follower
439 
440  if (dv < 0
441  // overtaking on the right on an uncongested highway is forbidden (noOvertakeLCLeft)
443  // not enough space to overtake? (we will start to brake when approaching a dead end)
445  // not enough time to overtake?
446  || dv * remainingSeconds < overtakeDist) {
447  // cannot overtake
448  msgPass.informNeighLeader(new Info(-1, dir | LCA_AMBLOCKINGLEADER), &myVehicle);
449  // slow down smoothly to follow leader
450  const SUMOReal targetSpeed = myCarFollowModel.followSpeed(
451  &myVehicle, myVehicle.getSpeed(), neighLead.second, nv->getSpeed(), nv->getCarFollowModel().getMaxDecel());
452  if (targetSpeed < myVehicle.getSpeed()) {
453  // slow down smoothly to follow leader
455  MAX2(MIN_FALLBEHIND, (myVehicle.getSpeed() - targetSpeed) / remainingSeconds)));
456  //const SUMOReal nextSpeed = MAX2((SUMOReal)0, MIN2(plannedSpeed, myVehicle.getSpeed() - decel));
457  const SUMOReal nextSpeed = MIN2(plannedSpeed, myVehicle.getSpeed() - decel);
458 #ifdef DEBUG_INFORMER
459  if (DEBUG_COND) {
460  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
461  << " cannot overtake leader nv=" << nv->getID()
462  << " dv=" << dv
463  << " remainingSeconds=" << remainingSeconds
464  << " targetSpeed=" << targetSpeed
465  << " nextSpeed=" << nextSpeed
466  << "\n";
467  }
468 #endif
469  myVSafes.push_back(nextSpeed);
470  return nextSpeed;
471  } else {
472  // leader is fast enough anyway
473 #ifdef DEBUG_INFORMER
474  if (DEBUG_COND) {
475  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
476  << " cannot overtake fast leader nv=" << nv->getID()
477  << " dv=" << dv
478  << " remainingSeconds=" << remainingSeconds
479  << " targetSpeed=" << targetSpeed
480  << "\n";
481  }
482 #endif
483  myVSafes.push_back(targetSpeed);
484  return plannedSpeed;
485  }
486  } else {
487  // overtaking, leader should not accelerate
488 #ifdef DEBUG_INFORMER
489  if (DEBUG_COND) {
490  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
491  << " wants to overtake leader nv=" << nv->getID()
492  << " dv=" << dv
493  << " remainingSeconds=" << remainingSeconds
494  << " currentGap=" << neighLead.second
496  << " overtakeDist=" << overtakeDist
497  << "\n";
498  }
499 #endif
500  msgPass.informNeighLeader(new Info(nv->getSpeed(), dir | LCA_AMBLOCKINGLEADER), &myVehicle);
501  return -1;
502  }
503  } else if (neighLead.first != 0) { // (remainUnblocked)
504  // we are not blocked now. make sure we stay far enough from the leader
505  MSVehicle* nv = neighLead.first;
506  const SUMOReal nextNVSpeed = nv->getSpeed() - HELP_OVERTAKE; // conservative
507  const SUMOReal dv = SPEED2DIST(myVehicle.getSpeed() - nextNVSpeed);
508  const SUMOReal targetSpeed = myCarFollowModel.followSpeed(
509  &myVehicle, myVehicle.getSpeed(), neighLead.second - dv, nextNVSpeed, nv->getCarFollowModel().getMaxDecel());
510  myVSafes.push_back(targetSpeed);
511 #ifdef DEBUG_INFORMER
512  if (DEBUG_COND) {
513  std::cout << " not blocked by leader nv=" << nv->getID()
514  << " nvSpeed=" << nv->getSpeed()
515  << " gap=" << neighLead.second
516  << " nextGap=" << neighLead.second - dv
518  << " targetSpeed=" << targetSpeed
519  << "\n";
520  }
521 #endif
522  return MIN2(targetSpeed, plannedSpeed);
523  } else {
524  // not overtaking
525  return plannedSpeed;
526  }
527 }
528 
529 
530 void
532  int blocked,
533  int dir,
534  const std::pair<MSVehicle*, SUMOReal>& neighFollow,
535  SUMOReal remainingSeconds,
536  SUMOReal plannedSpeed) {
537  if ((blocked & LCA_BLOCKED_BY_FOLLOWER) != 0) {
538  assert(neighFollow.first != 0);
539  MSVehicle* nv = neighFollow.first;
540 #ifdef DEBUG_INFORMER
541  if (DEBUG_COND) {
542  std::cout << " blocked by follower nv=" << nv->getID() << " nvSpeed=" << nv->getSpeed() << " needGap="
543  << nv->getCarFollowModel().getSecureGap(nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel()) << " planned=" << plannedSpeed << "\n";
544  }
545 #endif
546 
547  // are we fast enough to cut in without any help?
548  if (plannedSpeed - nv->getSpeed() >= HELP_OVERTAKE) {
549  const SUMOReal neededGap = nv->getCarFollowModel().getSecureGap(nv->getSpeed(), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
550  if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->getSpeed())) {
551 #ifdef DEBUG_INFORMER
552  if (DEBUG_COND) {
553  std::cout << " wants to cut in before nv=" << nv->getID() << " without any help neededGap=" << neededGap << "\n";
554  }
555 #endif
556  // follower might even accelerate but not to much
557  msgPass.informNeighFollower(new Info(plannedSpeed - HELP_OVERTAKE, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
558  return;
559  }
560  }
561  // decide whether we will request help to cut in before the follower or allow to be overtaken
562 
563  // PARAMETERS
564  // assume other vehicle will assume the equivalent of 1 second of
565  // maximum deceleration to help us (will probably be spread over
566  // multiple seconds)
567  // -----------
568  const SUMOReal helpDecel = nv->getCarFollowModel().getMaxDecel() * HELP_DECEL_FACTOR ;
569 
570  // change in the gap between ego and blocker over 1 second (not STEP!)
571  const SUMOReal neighNewSpeed = MAX2((SUMOReal)0, nv->getSpeed() - ACCEL2SPEED(helpDecel));
572  const SUMOReal neighNewSpeed1s = MAX2((SUMOReal)0, nv->getSpeed() - helpDecel);
573  const SUMOReal dv = plannedSpeed - neighNewSpeed1s;
574  // new gap between follower and self in case the follower does brake for 1s
575  const SUMOReal decelGap = neighFollow.second + dv;
576  const SUMOReal secureGap = nv->getCarFollowModel().getSecureGap(neighNewSpeed1s, plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
577 #ifdef DEBUG_INFORMER
578  if (DEBUG_COND) {
579  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
580  << " egoV=" << myVehicle.getSpeed()
581  << " egoNV=" << plannedSpeed
582  << " nvNewSpeed=" << neighNewSpeed
583  << " nvNewSpeed1s=" << neighNewSpeed1s
584  << " deltaGap=" << dv
585  << " decelGap=" << decelGap
586  << " secGap=" << secureGap
587  << "\n";
588  }
589 #endif
590  if (decelGap > 0 && decelGap >= secureGap) {
591  // if the blocking neighbor brakes it could actually help
592  // how hard does it actually need to be?
593  // to be safe in the next step the following equation has to hold:
594  // vsafe <= followSpeed(gap=currentGap - SPEED2DIST(vsafe), ...)
595  // we compute an upper bound on vsafe by doing the computation twice
596  const SUMOReal vsafe1 = MAX2(neighNewSpeed, nv->getCarFollowModel().followSpeed(
597  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel()));
598  const SUMOReal vsafe = MAX2(neighNewSpeed, nv->getCarFollowModel().followSpeed(
599  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed - vsafe1), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel()));
600  // the following assertion cannot be guaranteed because the CFModel handles small gaps differently, see MSCFModel::maximumSafeStopSpeed
601  // assert(vsafe <= vsafe1);
602  msgPass.informNeighFollower(new Info(vsafe, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
603 #ifdef DEBUG_INFORMER
604  if (DEBUG_COND) {
605  std::cout << " wants to cut in before nv=" << nv->getID()
606  << " vsafe1=" << vsafe1
607  << " vsafe=" << vsafe
608  << " newSecGap=" << nv->getCarFollowModel().getSecureGap(vsafe, plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel())
609  << "\n";
610  }
611 #endif
612  } else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap + POSITION_EPS)) {
613  // decelerating once is sufficient to open up a large enough gap in time
614  msgPass.informNeighFollower(new Info(neighNewSpeed, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
615 #ifdef DEBUG_INFORMER
616  if (DEBUG_COND) {
617  std::cout << " wants to cut in before nv=" << nv->getID() << " (eventually)\n";
618  }
619 #endif
620  } else if (dir == LCA_MRIGHT && !myAllowOvertakingRight && !nv->congested()) {
621  const SUMOReal vhelp = MAX2(neighNewSpeed, HELP_OVERTAKE);
622  msgPass.informNeighFollower(new Info(vhelp, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
623 #ifdef DEBUG_INFORMER
624  if (DEBUG_COND) {
625  std::cout << " wants to cut in before nv=" << nv->getID() << " (nv cannot overtake right)\n";
626  }
627 #endif
628  } else {
630  if (nv->getSpeed() > myVehicle.getSpeed() &&
632  || (dir == LCA_MLEFT && plannedSpeed > CUT_IN_LEFT_SPEED_THRESHOLD) // VARIANT_22 (slowDownLeft)
633  // XXX this is a hack to determine whether the vehicles is on an on-ramp. This information should be retrieved from the network itself
634  || (dir == LCA_MLEFT && myLeftSpace > MAX_ONRAMP_LENGTH)
635  )) {
636  // let the follower slow down to increase the likelyhood that later vehicles will be slow enough to help
637  // follower should still be fast enough to open a gap
638  vhelp = MAX2(neighNewSpeed, myVehicle.getSpeed() + HELP_OVERTAKE);
639 #ifdef DEBUG_INFORMER
640  if (DEBUG_COND) {
641  std::cout << " wants right follower to slow down a bit\n";
642  }
643 #endif
644  if ((nv->getSpeed() - myVehicle.getSpeed()) / helpDecel < remainingSeconds) {
645 #ifdef DEBUG_INFORMER
646  if (DEBUG_COND) {
647  std::cout << " wants to cut in before right follower nv=" << nv->getID() << " (eventually)\n";
648  }
649 #endif
650  msgPass.informNeighFollower(new Info(vhelp, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
651  return;
652  }
653  }
654  msgPass.informNeighFollower(new Info(vhelp, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
655  // this follower is supposed to overtake us. slow down smoothly to allow this
656  const SUMOReal overtakeDist = (neighFollow.second // follower reaches ego back
657  + myVehicle.getVehicleType().getLengthWithGap() // follower reaches ego front
658  + nv->getVehicleType().getLength() // follower back at ego front
659  + myVehicle.getCarFollowModel().getSecureGap( // follower has safe dist to ego
660  plannedSpeed, vhelp, nv->getCarFollowModel().getMaxDecel()));
661  // speed difference to create a sufficiently large gap
662  const SUMOReal needDV = overtakeDist / remainingSeconds;
663  // make sure the deceleration is not to strong
664  myVSafes.push_back(MAX2(vhelp - needDV, myVehicle.getSpeed() - ACCEL2SPEED(myVehicle.getCarFollowModel().getMaxDecel())));
665 
666 #ifdef DEBUG_INFORMER
667  if (DEBUG_COND) {
668  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
669  << " veh=" << myVehicle.getID()
670  << " wants to be overtaken by=" << nv->getID()
671  << " overtakeDist=" << overtakeDist
672  << " vneigh=" << nv->getSpeed()
673  << " vhelp=" << vhelp
674  << " needDV=" << needDV
675  << " vsafe=" << myVSafes.back()
676  << "\n";
677  }
678 #endif
679  }
680  } else if (neighFollow.first != 0) {
681  // we are not blocked no, make sure it remains that way
682  MSVehicle* nv = neighFollow.first;
683  const SUMOReal vsafe1 = nv->getCarFollowModel().followSpeed(
684  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
685  const SUMOReal vsafe = nv->getCarFollowModel().followSpeed(
686  nv, nv->getSpeed(), neighFollow.second + SPEED2DIST(plannedSpeed - vsafe1), plannedSpeed, myVehicle.getCarFollowModel().getMaxDecel());
687  msgPass.informNeighFollower(new Info(vsafe, dir), &myVehicle);
688 #ifdef DEBUG_INFORMER
689  if (DEBUG_COND) {
690  std::cout << " wants to cut in before non-blocking follower nv=" << nv->getID() << "\n";
691  }
692 #endif
693  }
694 }
695 
696 
697 void
699  // keep information about strategic change direction
702  myLeftSpace = 0;
703  myVSafes.clear();
704  myDontBrake = false;
705  // truncate to work around numerical instability between different builds
706  mySpeedGainProbability = ceil(mySpeedGainProbability * 100000.0) * 0.00001;
707  myKeepRightProbability = ceil(myKeepRightProbability * 100000.0) * 0.00001;
708 }
709 
710 
711 void
713  myOwnState = 0;
716  if (myVehicle.getBestLaneOffset() == 0) {
717  // if we are not yet on our best lane there might still be unseen blockers
718  // (during patchSpeed)
720  myLeftSpace = 0;
721  }
723  myVSafes.clear();
724  myDontBrake = false;
725 }
726 
727 
728 int
730  int laneOffset,
732  int blocked,
733  const std::pair<MSVehicle*, SUMOReal>& leader,
734  const std::pair<MSVehicle*, SUMOReal>& neighLead,
735  const std::pair<MSVehicle*, SUMOReal>& neighFollow,
736  const MSLane& neighLane,
737  const std::vector<MSVehicle::LaneQ>& preb,
738  MSVehicle** lastBlocked,
739  MSVehicle** firstBlocked) {
740  assert(laneOffset == 1 || laneOffset == -1);
741  const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
742  // compute bestLaneOffset
743  MSVehicle::LaneQ curr, neigh, best;
744  int bestLaneOffset = 0;
745  SUMOReal currentDist = 0;
746  SUMOReal neighDist = 0;
747  int currIdx = 0;
748  MSLane* prebLane = myVehicle.getLane();
749  if (prebLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
750  // internal edges are not kept inside the bestLanes structure
751  prebLane = prebLane->getLinkCont()[0]->getLane();
752  }
753  const bool checkOpposite = &neighLane.getEdge() != &myVehicle.getLane()->getEdge();
754  const int prebOffset = (checkOpposite ? 0 : laneOffset);
755  for (int p = 0; p < (int) preb.size(); ++p) {
756  if (preb[p].lane == prebLane && p + laneOffset >= 0) {
757  assert(p + prebOffset < (int)preb.size());
758  curr = preb[p];
759  neigh = preb[p + prebOffset];
760  currentDist = curr.length;
761  neighDist = neigh.length;
762  bestLaneOffset = curr.bestLaneOffset;
763  // VARIANT_13 (equalBest)
764  if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
765 #ifdef DEBUG_WANTS_CHANGE
766  if (DEBUG_COND) {
767  std::cout << STEPS2TIME(currentTime)
768  << " veh=" << myVehicle.getID()
769  << " bestLaneOffsetOld=" << bestLaneOffset
770  << " bestLaneOffsetNew=" << laneOffset
771  << "\n";
772  }
773 #endif
774  bestLaneOffset = prebOffset;
775  }
776  best = preb[p + bestLaneOffset];
777  currIdx = p;
778  break;
779  }
780  }
781  // direction specific constants
782  const bool right = (laneOffset == -1);
783  if (isOpposite() && right) {
784  neigh = preb[preb.size() - 1];
785  curr = neigh;
786  best = neigh;
787  bestLaneOffset = -1;
788  curr.bestLaneOffset = -1;
789  neighDist = neigh.length;
790  currentDist = curr.length;
791  }
793  const int lca = (right ? LCA_RIGHT : LCA_LEFT);
794  const int mLca = (right ? LCA_MRIGHT : LCA_MLEFT);
795  const int lcaCounter = (right ? LCA_LEFT : LCA_RIGHT);
796  const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
797  // keep information about being a leader/follower
798  int ret = (myOwnState & 0xffff0000);
799  int req = 0; // the request to change or stay
800 
801  // VARIANT_5 (disableAMBACKBLOCKER1)
802  /*
803  if (leader.first != 0
804  && (myOwnState & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0
805  && (leader.first->getLaneChangeModel().getOwnState() & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) {
806 
807  myOwnState &= (0xffffffff - LCA_AMBLOCKINGFOLLOWER_DONTBRAKE);
808  if (myVehicle.getSpeed() > SUMO_const_haltingSpeed) {
809  myOwnState |= LCA_AMBACKBLOCKER;
810  } else {
811  ret |= LCA_AMBACKBLOCKER;
812  myDontBrake = true;
813  }
814  }
815  */
816 
817 #ifdef DEBUG_WANTS_CHANGE
818  if (DEBUG_COND) {
819  std::cout << SIMTIME
820  << " veh=" << myVehicle.getID()
821  << " _wantsChange state=" << myOwnState
822  << " myVSafes=" << toString(myVSafes)
823  << " firstBlocked=" << Named::getIDSecure(*firstBlocked)
824  << " lastBlocked=" << Named::getIDSecure(*lastBlocked)
825  << " leader=" << Named::getIDSecure(leader.first)
826  << " leaderGap=" << leader.second
827  << " neighLead=" << Named::getIDSecure(neighLead.first)
828  << " neighLeadGap=" << neighLead.second
829  << " neighFollow=" << Named::getIDSecure(neighFollow.first)
830  << " neighFollowGap=" << neighFollow.second
831  << "\n";
832  }
833 #endif
834 
835  ret = slowDownForBlocked(lastBlocked, ret);
836  // VARIANT_14 (furtherBlock)
837  if (lastBlocked != firstBlocked) {
838  ret = slowDownForBlocked(firstBlocked, ret);
839  }
840 
841 
842  // we try to estimate the distance which is necessary to get on a lane
843  // we have to get on in order to keep our route
844  // we assume we need something that depends on our velocity
845  // and compare this with the free space on our wished lane
846  //
847  // if the free space is somehow less than the space we need, we should
848  // definitely try to get to the desired lane
849  //
850  // this rule forces our vehicle to change the lane if a lane changing is necessary soon
851  // lookAheadDistance:
852  // we do not want the lookahead distance to change all the time so we discrectize the speed a bit
853 
854  // VARIANT_18 (laHyst)
857  } else {
860  }
861  //myLookAheadSpeed = myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle);
862 
863  //SUMOReal laDist = laSpeed > LOOK_FORWARD_SPEED_DIVIDER
864  // ? laSpeed * LOOK_FORWARD_FAR
865  // : laSpeed * LOOK_FORWARD_NEAR;
867  laDist += myVehicle.getVehicleType().getLengthWithGap() * (SUMOReal) 2.;
868 
869  // react to a stopped leader on the current lane
870  if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped()) {
871  // value is doubled for the check since we change back and forth
872  laDist = 0.5 * (myVehicle.getVehicleType().getLengthWithGap()
873  + leader.first->getVehicleType().getLengthWithGap());
874  }
875 
876  // free space that is available for changing
877  //const SUMOReal neighSpeed = (neighLead.first != 0 ? neighLead.first->getSpeed() :
878  // neighFollow.first != 0 ? neighFollow.first->getSpeed() :
879  // best.lane->getSpeedLimit());
880  // @note: while this lets vehicles change earlier into the correct direction
881  // it also makes the vehicles more "selfish" and prevents changes which are necessary to help others
882 
883  // VARIANT_15 (insideRoundabout)
884  int roundaboutEdgesAhead = 0;
885  for (std::vector<MSLane*>::iterator it = curr.bestContinuations.begin(); it != curr.bestContinuations.end(); ++it) {
886  if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
887  roundaboutEdgesAhead += 1;
888  } else if (roundaboutEdgesAhead > 0) {
889  // only check the next roundabout
890  break;
891  }
892  }
893  int roundaboutEdgesAheadNeigh = 0;
894  for (std::vector<MSLane*>::iterator it = neigh.bestContinuations.begin(); it != neigh.bestContinuations.end(); ++it) {
895  if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
896  roundaboutEdgesAheadNeigh += 1;
897  } else if (roundaboutEdgesAheadNeigh > 0) {
898  // only check the next roundabout
899  break;
900  }
901  }
902  if (roundaboutEdgesAhead > 1) {
903  currentDist += roundaboutEdgesAhead * ROUNDABOUT_DIST_BONUS * myCooperativeParam;
904  neighDist += roundaboutEdgesAheadNeigh * ROUNDABOUT_DIST_BONUS * myCooperativeParam;
905  }
906 #ifdef DEBUG_WANTS_CHANGE
907  if (DEBUG_COND) {
908  if (roundaboutEdgesAhead > 0) {
909  std::cout << " roundaboutEdgesAhead=" << roundaboutEdgesAhead << " roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh << "\n";
910  }
911  }
912 #endif
913 
914  const SUMOReal usableDist = (currentDist - posOnLane - best.occupation * JAM_FACTOR);
915  //- (best.lane->getVehicleNumber() * neighSpeed)); // VARIANT 9 jfSpeed
916  const SUMOReal maxJam = MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
917  const SUMOReal neighLeftPlace = MAX2((SUMOReal) 0, neighDist - posOnLane - maxJam);
918 
919 #ifdef DEBUG_WANTS_CHANGE
920  if (DEBUG_COND) {
921  std::cout << STEPS2TIME(currentTime)
922  << " veh=" << myVehicle.getID()
923  << " laSpeed=" << myLookAheadSpeed
924  << " laDist=" << laDist
925  << " currentDist=" << currentDist
926  << " usableDist=" << usableDist
927  << " bestLaneOffset=" << bestLaneOffset
928  << " best.occupation=" << best.occupation
929  << " best.length=" << best.length
930  << " maxJam=" << maxJam
931  << " neighLeftPlace=" << neighLeftPlace
932  << "\n";
933  }
934 #endif
935 
936  if (changeToBest && bestLaneOffset == curr.bestLaneOffset
937  && (currentDistDisallows(usableDist, bestLaneOffset, laDist))) {
939  ret = ret | lca | LCA_STRATEGIC | LCA_URGENT;
940  } else {
941  // VARIANT_20 (noOvertakeRight)
942  if (!myAllowOvertakingRight && !right && !myVehicle.congested() && neighLead.first != 0) {
943  // check for slower leader on the left. we should not overtake but
944  // rather move left ourselves (unless congested)
945  MSVehicle* nv = neighLead.first;
946  if (nv->getSpeed() < myVehicle.getSpeed()) {
947  const SUMOReal vSafe = myCarFollowModel.followSpeed(
948  &myVehicle, myVehicle.getSpeed(), neighLead.second, nv->getSpeed(), nv->getCarFollowModel().getMaxDecel());
949  myVSafes.push_back(vSafe);
950  if (vSafe < myVehicle.getSpeed()) {
952  }
953 #ifdef DEBUG_WANTS_CHANGE
954  if (DEBUG_COND) {
955  std::cout << STEPS2TIME(currentTime)
956  << " avoid overtaking on the right nv=" << nv->getID()
957  << " nvSpeed=" << nv->getSpeed()
958  << " mySpeedGainProbability=" << mySpeedGainProbability
959  << " plannedSpeed=" << myVSafes.back()
960  << "\n";
961  }
962 #endif
963  }
964  }
965 
966  if (!changeToBest && (currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
967  // the opposite lane-changing direction should be done than the one examined herein
968  // we'll check whether we assume we could change anyhow and get back in time...
969  //
970  // this rule prevents the vehicle from moving in opposite direction of the best lane
971  // unless the way till the end where the vehicle has to be on the best lane
972  // is long enough
973 #ifdef DEBUG_WANTS_CHANGE
974  if (DEBUG_COND) {
975  std::cout << " veh=" << myVehicle.getID() << " could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace << "\n";
976  }
977 #endif
978  ret = ret | LCA_STAY | LCA_STRATEGIC;
979  } else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
980  // the current lane is the best and a lane-changing would cause a situation
981  // of which we assume we will not be able to return to the lane we have to be on.
982  // this rule prevents the vehicle from leaving the current, best lane when it is
983  // close to this lane's end
984 #ifdef DEBUG_WANTS_CHANGE
985  if (DEBUG_COND) {
986  std::cout << " veh=" << myVehicle.getID() << " could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace << "\n";
987  }
988 #endif
989  ret = ret | LCA_STAY | LCA_STRATEGIC;
990  } else if (bestLaneOffset == 0
991  && (leader.first == 0 || !leader.first->isStopped())
992  && neigh.bestContinuations.back()->getLinkCont().size() != 0
993  && roundaboutEdgesAhead == 0
994  && neighDist < TURN_LANE_DIST) {
995  // VARIANT_21 (stayOnBest)
996  // we do not want to leave the best lane for a lane which leads elsewhere
997  // unless our leader is stopped or we are approaching a roundabout
998 #ifdef DEBUG_WANTS_CHANGE
999  if (DEBUG_COND) {
1000  std::cout << " veh=" << myVehicle.getID() << " does not want to leave the bestLane (neighDist=" << neighDist << ")\n";
1001  }
1002 #endif
1003  ret = ret | LCA_STAY | LCA_STRATEGIC;
1004  }
1005  }
1006  // check for overriding TraCI requests
1007 #ifdef DEBUG_WANTS_CHANGE
1008  if (DEBUG_COND) {
1009  std::cout << STEPS2TIME(currentTime) << " veh=" << myVehicle.getID() << " ret=" << ret;
1010  }
1011 #endif
1013  if ((ret & lcaCounter) != 0) {
1014  // we are not interested in traci requests for the opposite direction here
1015  ret &= ~(LCA_TRACI | lcaCounter | LCA_URGENT);
1016  }
1017 #ifdef DEBUG_WANTS_CHANGE
1018  if (DEBUG_COND) {
1019  std::cout << " retAfterInfluence=" << ret << "\n";
1020  }
1021 #endif
1022 
1023  if ((ret & LCA_STAY) != 0) {
1024  return ret;
1025  }
1026  if ((ret & LCA_URGENT) != 0) {
1027  // prepare urgent lane change maneuver
1028  // save the left space
1029  myLeftSpace = currentDist - posOnLane;
1030  if (changeToBest && abs(bestLaneOffset) > 1) {
1031  // there might be a vehicle which needs to counter-lane-change one lane further and we cannot see it yet
1032 #ifdef DEBUG_WANTS_CHANGE
1033  if (DEBUG_COND) {
1034  std::cout << " reserving space for unseen blockers\n";
1035  }
1036 #endif
1037  myLeadingBlockerLength = MAX2((SUMOReal)(right ? 20.0 : 40.0), myLeadingBlockerLength);
1038  }
1039 
1040  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#1
1041  // if there is a leader and he wants to change to the opposite direction
1042  saveBlockerLength(neighLead.first, lcaCounter);
1043  if (*firstBlocked != neighLead.first) {
1044  saveBlockerLength(*firstBlocked, lcaCounter);
1045  }
1046 
1047  const SUMOReal remainingSeconds = ((ret & LCA_TRACI) == 0 ?
1050  const SUMOReal plannedSpeed = informLeader(msgPass, blocked, mLca, neighLead, remainingSeconds);
1051  if (plannedSpeed >= 0) {
1052  // maybe we need to deal with a blocking follower
1053  informFollower(msgPass, blocked, mLca, neighFollow, remainingSeconds, plannedSpeed);
1054  }
1055 
1056 #ifdef DEBUG_WANTS_CHANGE
1057  if (DEBUG_COND) {
1058  std::cout << STEPS2TIME(currentTime)
1059  << " veh=" << myVehicle.getID()
1060  << " myLeftSpace=" << myLeftSpace
1061  << " remainingSeconds=" << remainingSeconds
1062  << " plannedSpeed=" << plannedSpeed
1063  << "\n";
1064  }
1065 #endif
1066  return ret;
1067  }
1068 
1069  // VARIANT_15
1070  if (roundaboutEdgesAhead > 1) {
1071  // try to use the inner lanes of a roundabout to increase throughput
1072  // unless we are approaching the exit
1073  if (lca == LCA_LEFT) {
1074  req = ret | lca | LCA_COOPERATIVE;
1075  } else {
1076  req = ret | LCA_STAY | LCA_COOPERATIVE;
1077  }
1078  if (!cancelRequest(req)) {
1079  return ret | req;
1080  }
1081  }
1082 
1083  // let's also regard the case where the vehicle is driving on a highway...
1084  // in this case, we do not want to get to the dead-end of an on-ramp
1085  if (right) {
1086  if (bestLaneOffset == 0 && myVehicle.getLane()->getSpeedLimit() > 80. / 3.6 && myLookAheadSpeed > SUMO_const_haltingSpeed) {
1087 #ifdef DEBUG_WANTS_CHANGE
1088  if (DEBUG_COND) {
1089  std::cout << " veh=" << myVehicle.getID() << " does not want to get stranded on the on-ramp of a highway\n";
1090  }
1091 #endif
1092  req = ret | LCA_STAY | LCA_STRATEGIC;
1093  if (!cancelRequest(req)) {
1094  return ret | req;
1095  }
1096  }
1097  }
1098  // --------
1099 
1100  // -------- make place on current lane if blocking follower
1101  //if (amBlockingFollowerPlusNB()) {
1102  // std::cout << myVehicle.getID() << ", " << currentDistAllows(neighDist, bestLaneOffset, laDist)
1103  // << " neighDist=" << neighDist
1104  // << " currentDist=" << currentDist
1105  // << "\n";
1106  //}
1107  const SUMOReal inconvenience = MIN2((SUMOReal)1.0, (laneOffset < 0
1111  && (inconvenience <= myCooperativeParam)
1112  //&& ((myOwnState & lcaCounter) == 0) // VARIANT_6 : counterNoHelp
1113  && (changeToBest || currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1114 
1115  // VARIANT_2 (nbWhenChangingToHelp)
1116 #ifdef DEBUG_WANTS_CHANGE
1117  if (DEBUG_COND) {
1118  std::cout << STEPS2TIME(currentTime)
1119  << " veh=" << myVehicle.getID()
1120  << " wantsChangeToHelp=" << (right ? "right" : "left")
1121  << " state=" << myOwnState
1122  << (((myOwnState & lcaCounter) != 0) ? " (counter)" : "")
1123  << "\n";
1124  }
1125 #endif
1126  req = ret | lca | LCA_COOPERATIVE | LCA_URGENT ;//| LCA_CHANGE_TO_HELP;
1127  if (!cancelRequest(req)) {
1128  return ret | req;
1129  }
1130  }
1131 
1132  // --------
1133 
1134 
1137  //if ((blocked & LCA_BLOCKED) != 0) {
1138  // return ret;
1139  //}
1141 
1142  // -------- higher speed
1143  //if ((congested(neighLead.first) && neighLead.second < 20) || predInteraction(leader.first)) { //!!!
1144  // return ret;
1145  //}
1146 
1147  // followSpeed returns the speed after accelerating for TS but we are
1148  // interested in the speed after 1s
1149  const SUMOReal correctedSpeed = (myVehicle.getSpeed()
1152 
1153  SUMOReal thisLaneVSafe = myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle);
1154  SUMOReal neighLaneVSafe = neighLane.getVehicleMaxSpeed(&myVehicle);
1155  if (neighLead.first == 0) {
1156  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, correctedSpeed, neighDist, 0, 0));
1157  } else {
1158  // @todo: what if leader is below safe gap?!!!
1159  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(
1160  &myVehicle, correctedSpeed, neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1161  }
1162  if (leader.first == 0) {
1163  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, correctedSpeed, currentDist, 0, 0));
1164  } else {
1165  // @todo: what if leader is below safe gap?!!!
1166  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, correctedSpeed, leader.second, leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1167  }
1168 #ifdef DEBUG_WANTS_CHANGE
1169  if (DEBUG_COND) {
1170  std::cout << STEPS2TIME(currentTime)
1171  << " veh=" << myVehicle.getID()
1172  << " currentDist=" << currentDist
1173  << " neighDist=" << neighDist
1174  << "\n";
1175  }
1176 #endif
1177 
1179  thisLaneVSafe = MIN2(thisLaneVSafe, vMax);
1180  neighLaneVSafe = MIN2(neighLaneVSafe, vMax);
1181  const SUMOReal relativeGain = (neighLaneVSafe - thisLaneVSafe) / MAX2(neighLaneVSafe,
1183 
1184  if (right) {
1185  // ONLY FOR CHANGING TO THE RIGHT
1186  if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1187  // ok, the current lane is faster than the right one...
1188  if (mySpeedGainProbability < 0) {
1189  mySpeedGainProbability *= pow(0.5, TS);
1190  }
1191  } else {
1192  // ok, the current lane is not (much) faster than the right one
1193  // @todo recheck the 5 km/h discount on thisLaneVSafe
1194 
1195  // do not promote changing to the left just because changing to the
1196  // right is bad
1197  if (mySpeedGainProbability < 0 || relativeGain > 0) {
1198  mySpeedGainProbability -= TS * relativeGain;
1199  }
1200 
1201  // honor the obligation to keep right (Rechtsfahrgebot)
1202  // XXX consider fast approaching followers on the current lane
1203  //const SUMOReal vMax = myLookAheadSpeed;
1204  const SUMOReal acceptanceTime = KEEP_RIGHT_ACCEPTANCE * vMax * MAX2((SUMOReal)1, myVehicle.getSpeed()) / myVehicle.getLane()->getSpeedLimit();
1205  SUMOReal fullSpeedGap = MAX2((SUMOReal)0, neighDist - myVehicle.getCarFollowModel().brakeGap(vMax));
1206  SUMOReal fullSpeedDrivingSeconds = MIN2(acceptanceTime, fullSpeedGap / vMax);
1207  if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1208  fullSpeedGap = MAX2((SUMOReal)0, MIN2(fullSpeedGap,
1209  neighLead.second - myVehicle.getCarFollowModel().getSecureGap(
1210  vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1211  fullSpeedDrivingSeconds = MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1212  }
1213  const SUMOReal deltaProb = (myChangeProbThresholdRight
1214  * STEPS2TIME(DELTA_T)
1215  * (fullSpeedDrivingSeconds / acceptanceTime) / KEEP_RIGHT_TIME);
1216  myKeepRightProbability -= TS * deltaProb;
1217 
1218 #ifdef DEBUG_WANTS_CHANGE
1219  if (DEBUG_COND) {
1220  std::cout << STEPS2TIME(currentTime)
1221  << " veh=" << myVehicle.getID()
1222  << " vMax=" << vMax
1223  << " neighDist=" << neighDist
1224  << " brakeGap=" << myVehicle.getCarFollowModel().brakeGap(myVehicle.getSpeed())
1225  << " leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1226  << " secGap=" << (neighLead.first == 0 ? -1 : myVehicle.getCarFollowModel().getSecureGap(
1227  myVehicle.getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1228  << " acceptanceTime=" << acceptanceTime
1229  << " fullSpeedGap=" << fullSpeedGap
1230  << " fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1231  << " dProb=" << deltaProb
1232  << " myKeepRightProbability=" << myKeepRightProbability
1233  << "\n";
1234  }
1235 #endif
1237  req = ret | lca | LCA_KEEPRIGHT;
1238  if (!cancelRequest(req)) {
1239  return ret | req;
1240  }
1241  }
1242  }
1243 
1244 #ifdef DEBUG_WANTS_CHANGE
1245  if (DEBUG_COND) {
1246  std::cout << STEPS2TIME(currentTime)
1247  << " veh=" << myVehicle.getID()
1248  << " speed=" << myVehicle.getSpeed()
1249  << " mySpeedGainProbability=" << mySpeedGainProbability
1250  << " thisLaneVSafe=" << thisLaneVSafe
1251  << " neighLaneVSafe=" << neighLaneVSafe
1252  << " relativeGain=" << relativeGain
1253  << " blocked=" << blocked
1254  << "\n";
1255  }
1256 #endif
1257 
1259  && neighDist / MAX2((SUMOReal) .1, myVehicle.getSpeed()) > 20.) { //./MAX2((SUMOReal) .1, myVehicle.getSpeed())) { // -.1
1260  req = ret | lca | LCA_SPEEDGAIN;
1261  if (!cancelRequest(req)) {
1262  return ret | req;
1263  }
1264  }
1265  } else {
1266  // ONLY FOR CHANGING TO THE LEFT
1267  if (thisLaneVSafe > neighLaneVSafe) {
1268  // this lane is better
1269  if (mySpeedGainProbability > 0) {
1270  mySpeedGainProbability *= pow(0.5, TS);
1271  }
1272  } else {
1273  // left lane is better
1274  mySpeedGainProbability += TS * relativeGain;
1275  }
1276  // VARIANT_19 (stayRight)
1277  //if (neighFollow.first != 0) {
1278  // MSVehicle* nv = neighFollow.first;
1279  // const SUMOReal secGap = nv->getCarFollowModel().getSecureGap(nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel());
1280  // if (neighFollow.second < secGap * KEEP_RIGHT_HEADWAY) {
1281  // // do not change left if it would inconvenience faster followers
1282  // return ret | LCA_STAY | LCA_SPEEDGAIN;
1283  // }
1284  //}
1285 
1286 #ifdef DEBUG_WANTS_CHANGE
1287  if (DEBUG_COND) {
1288  std::cout << STEPS2TIME(currentTime)
1289  << " veh=" << myVehicle.getID()
1290  << " speed=" << myVehicle.getSpeed()
1291  << " mySpeedGainProbability=" << mySpeedGainProbability
1292  << " thisLaneVSafe=" << thisLaneVSafe
1293  << " neighLaneVSafe=" << neighLaneVSafe
1294  << " relativeGain=" << relativeGain
1295  << " blocked=" << blocked
1296  << "\n";
1297  }
1298 #endif
1299  if (mySpeedGainProbability > myChangeProbThresholdLeft && neighDist / MAX2((SUMOReal) .1, myVehicle.getSpeed()) > 20.) { // .1
1300  req = ret | lca | LCA_SPEEDGAIN;
1301  if (!cancelRequest(req)) {
1302  return ret | req;
1303  }
1304  }
1305  }
1306  // --------
1307  if (changeToBest && bestLaneOffset == curr.bestLaneOffset
1308  && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1309  // change towards the correct lane, speedwise it does not hurt
1310  req = ret | lca | LCA_STRATEGIC;
1311  if (!cancelRequest(req)) {
1312  return ret | req;
1313  }
1314  }
1315 #ifdef DEBUG_WANTS_CHANGE
1316  if (DEBUG_COND) {
1317  std::cout << STEPS2TIME(currentTime)
1318  << " veh=" << myVehicle.getID()
1319  << " mySpeedGainProbability=" << mySpeedGainProbability
1320  << " myKeepRightProbability=" << myKeepRightProbability
1321  << " thisLaneVSafe=" << thisLaneVSafe
1322  << " neighLaneVSafe=" << neighLaneVSafe
1323  << "\n";
1324  }
1325 #endif
1326  return ret;
1327 }
1328 
1329 
1330 int
1332  // if this vehicle is blocking someone in front, we maybe decelerate to let him in
1333  if ((*blocked) != 0) {
1334  SUMOReal gap = (*blocked)->getPositionOnLane() - (*blocked)->getVehicleType().getLength() - myVehicle.getPositionOnLane() - myVehicle.getVehicleType().getMinGap();
1335 #ifdef DEBUG_SLOW_DOWN
1336  if (DEBUG_COND) {
1337  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
1338  << " veh=" << myVehicle.getID()
1339  << " blocked=" << Named::getIDSecure(*blocked)
1340  << " gap=" << gap
1341  << "\n";
1342  }
1343 #endif
1344  if (gap > POSITION_EPS) {
1345  //const bool blockedWantsUrgentRight = (((*blocked)->getLaneChangeModel().getOwnState() & LCA_RIGHT != 0)
1346  // && ((*blocked)->getLaneChangeModel().getOwnState() & LCA_URGENT != 0));
1347 
1349  //|| blockedWantsUrgentRight // VARIANT_10 (helpblockedRight)
1350  ) {
1351  if ((*blocked)->getSpeed() < SUMO_const_haltingSpeed) {
1352  state |= LCA_AMBACKBLOCKER_STANDING;
1353  } else {
1354  state |= LCA_AMBACKBLOCKER;
1355  }
1358  (SUMOReal)(gap - POSITION_EPS), (*blocked)->getSpeed(),
1359  (*blocked)->getCarFollowModel().getMaxDecel()));
1360  //(*blocked) = 0; // VARIANT_14 (furtherBlock)
1361  }
1362  }
1363  }
1364  return state;
1365 }
1366 
1367 
1368 void
1369 MSLCM_JE2013::saveBlockerLength(MSVehicle* blocker, int lcaCounter) {
1370 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1371  if (DEBUG_COND) {
1372  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
1373  << " veh=" << myVehicle.getID()
1374  << " saveBlockerLength blocker=" << Named::getIDSecure(blocker)
1375  << " bState=" << (blocker == 0 ? "None" : toString(blocker->getLaneChangeModel().getOwnState()))
1376  << "\n";
1377  }
1378 #endif
1379  if (blocker != 0 && (blocker->getLaneChangeModel().getOwnState() & lcaCounter) != 0) {
1380  // is there enough space in front of us for the blocker?
1383  if (blocker->getVehicleType().getLengthWithGap() <= potential) {
1384  // save at least his length in myLeadingBlockerLength
1386 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1387  if (DEBUG_COND) {
1388  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
1389  << " veh=" << myVehicle.getID()
1390  << " blocker=" << Named::getIDSecure(blocker)
1391  << " saving myLeadingBlockerLength=" << myLeadingBlockerLength
1392  << "\n";
1393  }
1394 #endif
1395  } else {
1396  // we cannot save enough space for the blocker. It needs to save
1397  // space for ego instead
1398 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1399  if (DEBUG_COND) {
1400  std::cout << STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())
1401  << " veh=" << myVehicle.getID()
1402  << " blocker=" << Named::getIDSecure(blocker)
1403  << " cannot save space=" << blocker->getVehicleType().getLengthWithGap()
1404  << " potential=" << potential
1405  << "\n";
1406  }
1407 #endif
1409  }
1410  }
1411 }
1412 /****************************************************************************/
1413 
void * inform(void *info, MSVehicle *sender)
#define LOOK_AHEAD_MIN_SPEED
const SUMOReal myCooperativeParam
Definition: MSLCM_JE2013.h:196
int _wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, SUMOReal > &leader, const std::pair< MSVehicle *, SUMOReal > &neighLead, const std::pair< MSVehicle *, SUMOReal > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
helper function for doing the actual work
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:567
bool debugVehicle() const
whether the current vehicles shall be debugged
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:81
SUMOReal getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
long long int SUMOTime
Definition: SUMOTime.h:43
The action is due to the default of keeping right "Rechtsfahrgebot".
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
The action is done to help someone else.
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
const SUMOReal myChangeProbThresholdLeft
Definition: MSLCM_JE2013.h:205
#define KEEP_RIGHT_TIME
#define min(a, b)
Definition: polyfonts.c:66
#define TURN_LANE_DIST
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:700
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:61
#define URGENCY
bool currentDistAllows(SUMOReal dist, int laneOffset, SUMOReal lookForwardDist)
Definition: MSLCM_JE2013.h:166
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:626
bool congested() const
Definition: MSVehicle.h:542
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle&#39;s follow speed (no dawdling)
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:475
SUMOReal myLeadingBlockerLength
Definition: MSLCM_JE2013.h:183
The car-following model abstraction.
Definition: MSCFModel.h:59
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
virtual ~MSLCM_JE2013()
Wants go to the right.
SUMOReal getLength() const
Get vehicle&#39;s length [m].
SUMOReal myLeftSpace
Definition: MSLCM_JE2013.h:184
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, SUMOReal > &leader, const std::pair< MSVehicle *, SUMOReal > &neighLead, const std::pair< MSVehicle *, SUMOReal > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
Called to examine whether the vehicle wants to change using the given laneOffset. This method gets th...
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:75
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:59
MSLCM_JE2013(MSVehicle &v)
std::vector< SUMOReal > myVSafes
Definition: MSLCM_JE2013.h:190
SUMOReal getSecureGap(const SUMOReal speed, const SUMOReal leaderSpeed, const SUMOReal leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum.
Definition: MSCFModel.h:272
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:350
#define TS
Definition: SUMOTime.h:52
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:254
Wants go to the left.
The action is due to the wish to be faster (tactical lc)
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:618
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
#define abs(a)
Definition: polyfonts.c:67
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2462
#define SIMTIME
Definition: SUMOTime.h:70
void informFollower(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, SUMOReal > &neighFollow, SUMOReal remainingSeconds, SUMOReal plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
#define LCA_RIGHT_IMPATIENCE
SUMOReal getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:375
Needs to stay on the current lane.
std::pair< SUMOReal, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
Definition: MSLCM_JE2013.h:171
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
const SUMOReal myStrategicParam
Definition: MSLCM_JE2013.h:195
A class responsible for exchanging messages between cars involved in lane-change interaction.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
#define max(a, b)
Definition: polyfonts.c:65
bool cancelRequest(int state)
whether the influencer cancels the given request
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time.
Definition: MSCFModel.h:234
#define CUT_IN_LEFT_SPEED_THRESHOLD
The action is urgent (to be defined by lc-model)
SUMOReal mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial ...
Definition: MSLCM_JE2013.h:177
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
void prepareStep()
#define RELGAIN_NORMALIZATION_MIN_SPEED
#define JAM_FACTOR
#define LOOK_FORWARD_RIGHT
bool amBlockingFollowerPlusNB()
Definition: MSLCM_JE2013.h:160
SUMOReal informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, SUMOReal > &neighLead, SUMOReal remainingSeconds)
SUMOReal _patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel &cfModel)
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
#define MAX_ONRAMP_LENGTH
T MIN2(T a, T b)
Definition: StdDefs.h:69
The action is needed to follow the route (navigational lc)
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap2pred) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
#define POSITION_EPS
Definition: config.h:187
SUMOReal getSpeedLimit() const
Returns the lane&#39;s maximum allowed speed.
Definition: MSLane.h:467
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:614
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:186
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:386
int myOwnState
The current state of the vehicle.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
#define HELP_OVERTAKE
const SUMOReal myKeepRightParam
Definition: MSLCM_JE2013.h:198
virtual void saveBlockerLength(SUMOReal length)
reserve space at the end of the lane to avoid dead locks
SUMOReal getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:178
#define HELP_DECEL_FACTOR
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3448
SUMOReal myKeepRightProbability
Definition: MSLCM_JE2013.h:181
#define LOOK_AHEAD_SPEED_MEMORY
#define ROUNDABOUT_DIST_BONUS
SUMOReal occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:622
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:630
SUMOReal myLookAheadSpeed
Definition: MSLCM_JE2013.h:188
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:97
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:410
SUMOReal getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:502
#define MIN_FALLBEHIND
The action is due to a TraCI request.
#define KEEP_RIGHT_ACCEPTANCE
#define SUMOReal
Definition: config.h:213
const SUMOReal myChangeProbThresholdRight
Definition: MSLCM_JE2013.h:204
#define LOOK_FORWARD_LEFT
#define NUMERICAL_EPS
Definition: config.h:160
#define DEBUG_COND
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1445
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:453
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:447
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:3472
The edge is an internal edge.
Definition: MSEdge.h:97
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
const MSCFModel & myCarFollowModel
The vehicle&#39;s car following model.
bool currentDistDisallows(SUMOReal dist, int laneOffset, SUMOReal lookForwardDist)
Definition: MSLCM_JE2013.h:163
const SUMOReal mySpeedGainParam
Definition: MSLCM_JE2013.h:197
Interface for lane-change models.
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:2836
bool hasLaneChanger() const
Definition: MSEdge.h:644
SUMOReal patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel &cfModel)
Called to adapt the speed in order to allow a lane change.
const std::string & getID() const
Returns the name of the vehicle.