Eclipse SUMO - Simulation of Urban MObility
MSLCM_DK2008.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2005-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 /****************************************************************************/
18 // A lane change model developed by D. Krajzewicz between 2004 and 2010
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #include <config.h>
26 
27 #include <iostream>
29 #include <microsim/MSEdge.h>
30 #include <microsim/MSLane.h>
31 #include <microsim/MSNet.h>
32 #include "MSLCM_DK2008.h"
33 
34 // ===========================================================================
35 // variable definitions
36 // ===========================================================================
37 // 80km/h will be the threshold for dividing between long/short foresight
38 #define LOOK_FORWARD_SPEED_DIVIDER 14.
39 
40 #define LOOK_FORWARD_FAR 15.
41 #define LOOK_FORWARD_NEAR 5.
42 
43 
44 
45 #define JAM_FACTOR 2.
46 #define JAM_FACTOR2 1.
47 
48 
49 // ===========================================================================
50 // member method definitions
51 // ===========================================================================
54  myChangeProbability(0),
55  myLeadingBlockerLength(0), myLeftSpace(0) {}
56 
58  changed();
59 }
60 
61 int
63  int laneOffset,
64  MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked,
65  const std::pair<MSVehicle*, double>& leader,
66  const std::pair<MSVehicle*, double>& neighLead,
67  const std::pair<MSVehicle*, double>& neighFollow,
68  const MSLane& neighLane,
69  const std::vector<MSVehicle::LaneQ>& preb,
70  MSVehicle** lastBlocked,
71  MSVehicle** firstBlocked) {
72  UNUSED_PARAMETER(firstBlocked);
73  return (laneOffset == -1 ?
74  wantsChangeToRight(msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked)
75  : wantsChangeToLeft(msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked));
76 
77 }
78 
79 
80 int
82  int blocked,
83  const std::pair<MSVehicle*, double>& leader,
84  const std::pair<MSVehicle*, double>& neighLead,
85  const std::pair<MSVehicle*, double>& neighFollow,
86  const MSLane& neighLane,
87  const std::vector<MSVehicle::LaneQ>& preb,
88  MSVehicle** lastBlocked,
89  MSVehicle** firstBlocked) {
90  UNUSED_PARAMETER(firstBlocked);
91  MSVehicle::LaneQ curr, best;
92  int bestLaneOffset = 0;
93  double currentDist = 0;
94  double neighDist = 0;
95  double neighExtDist = 0;
96  double currExtDist = 0;
97  int currIdx = 0;
98  MSLane* prebLane = myVehicle.getLane();
99  if (prebLane->getEdge().isInternal()) {
100  // internal edges are not kept inside the bestLanes structure
101  prebLane = prebLane->getLinkCont()[0]->getLane();
102  }
103  for (int p = 0; p < (int) preb.size(); ++p) {
104  if (preb[p].lane == prebLane && p > 0) {
105  curr = preb[p];
106  bestLaneOffset = curr.bestLaneOffset;
107  currentDist = curr.length;
108  currExtDist = curr.lane->getLength();
109  neighDist = preb[p - 1].length;
110  neighExtDist = preb[p - 1].lane->getLength();
111  best = preb[p + bestLaneOffset];
112  currIdx = p;
113  break;
114  }
115  }
116 
117  // keep information about being a leader/follower
118  int ret = (myOwnState & 0xffff0000);
119 
120  if (leader.first != 0
121  &&
123  &&
124  (leader.first->getLaneChangeModel().getOwnState()&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) {
125 
129  } else {
130  ret |= LCA_AMBACKBLOCKER;
131  myDontBrake = true;
132  }
133  }
134 
135  // process information about the last blocked vehicle
136  // if this vehicle is blocking someone in front, we maybe decelerate to let him in
137  if ((*lastBlocked) != nullptr) {
138  double gap = (*lastBlocked)->getPositionOnLane() - (*lastBlocked)->getVehicleType().getLength() - myVehicle.getPositionOnLane() - myVehicle.getVehicleType().getMinGap();
139  if (gap > 0.1) {
141  if ((*lastBlocked)->getSpeed() < SUMO_const_haltingSpeed) {
143  } else {
144  ret |= LCA_AMBACKBLOCKER;
145  }
146  myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), (double)(gap - 0.1), (*lastBlocked)->getSpeed(), (*lastBlocked)->getCarFollowModel().getMaxDecel()));
147  (*lastBlocked) = nullptr;
148  }
149  return ret;
150  }
151  }
152 
153  // we try to estimate the distance which is necessary to get on a lane
154  // we have to get on in order to keep our route
155  // we assume we need something that depends on our velocity
156  // and compare this with the free space on our wished lane
157  //
158  // if the free space is somehow less than the space we need, we should
159  // definitely try to get to the desired lane
160  //
161  // this rule forces our vehicle to change the lane if a lane changing is necessary soon
163  ? myVehicle.getSpeed() * (double) LOOK_FORWARD_FAR
164  : myVehicle.getSpeed() * (double) LOOK_FORWARD_NEAR;
165  rv += myVehicle.getVehicleType().getLengthWithGap() * (double) 2.;
166 
167  double tdist = currentDist - myVehicle.getPositionOnLane() - best.occupation * (double) JAM_FACTOR2;
168 
169  // assert(best.length > curr.length);
170  // XXX if (curr.length != best.length) && ...
171  if (fabs(best.length - curr.length) > MIN2((double) .1, best.lane->getLength()) && bestLaneOffset < 0 && currentDistDisallows(tdist/*currentDist*/, bestLaneOffset, rv)) {
172  informBlocker(msgPass, blocked, LCA_MRIGHT, neighLead, neighFollow);
173  if (neighLead.second > 0 && neighLead.second > leader.second) {
174  myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()) - (double) 0.5);
175  }
176 
177  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#1, right
178  // if there is a leader and he wants to change to left (we want to change to right)
179  if (neighLead.first != 0 && (neighLead.first->getLaneChangeModel().getOwnState()&LCA_LEFT) != 0) {
180  // save at least his length in myLeadingBlockerLength
181  myLeadingBlockerLength = MAX2(neighLead.first->getVehicleType().getLengthWithGap(), myLeadingBlockerLength);
182  // save the left space
183  myLeftSpace = currentDist - myVehicle.getPositionOnLane();
184  }
185  //
186 
187  return ret | LCA_RIGHT | LCA_STRATEGIC | LCA_URGENT;
188  }
189 
190 
191  // the opposite lane-changing direction should be done than the one examined herein
192  // we'll check whether we assume we could change anyhow and get back in time...
193  //
194  // this rule prevents the vehicle from moving in opposite direction of the best lane
195  // unless the way till the end where the vehicle has to be on the best lane
196  // is long enough
197  double maxJam = MAX2(preb[currIdx - 1].occupation, preb[currIdx].occupation);
198  double neighLeftPlace = MAX2((double) 0, neighDist - myVehicle.getPositionOnLane() - maxJam);
199  if (bestLaneOffset >= 0 && (currentDistDisallows(neighLeftPlace, bestLaneOffset + 2, rv))) {
200  // ...we will not change the lane if not
201  return ret | LCA_STAY | LCA_STRATEGIC;
202  }
203 
204 
205  // if the current lane is the best and a lane-changing would cause a situation
206  // of which we assume we will not be able to return to the lane we have to be on...
207  //
208  // this rule prevents the vehicle from leaving the current, best lane when it is
209  // close to this lane's end
210  if (currExtDist > neighExtDist && (neighLeftPlace * 2. < rv/*||currE[currIdx+1].length<currentDist*/)) {
211  return ret | LCA_STAY | LCA_STRATEGIC;
212  }
213 
214  // let's also regard the case where the vehicle is driving on a highway...
215  // in this case, we do not want to get to the dead-end of an on-ramp
216  //
217  // THIS RULE APPLIES ONLY TO CHANGING TO THE RIGHT LANE
218  if (bestLaneOffset == 0 && preb[currIdx - 1].bestLaneOffset != 0 && myVehicle.getLane()->getSpeedLimit() > 80. / 3.6) {
219  return ret | LCA_STAY | LCA_STRATEGIC;
220  }
221  // --------
222 
223  // -------- make place on current lane if blocking follower
225  &&
226  (currentDistAllows(neighDist, bestLaneOffset, rv) || neighDist >= currentDist)) {
227 
228  return ret | LCA_RIGHT | LCA_COOPERATIVE | LCA_URGENT;
229  }
230  // --------
231 
232 
233  // -------- security checks for krauss
234  // (vsafe fails when gap<0)
235  if ((blocked & LCA_BLOCKED) != 0) {
236  return ret;
237  }
238  // --------
239 
240  // -------- higher speed
241  if ((congested(neighLead.first) && neighLead.second < 20) || predInteraction(leader)) {
242  return ret;
243  }
244  double thisLaneVSafe = myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle);
245  double neighLaneVSafe = neighLane.getVehicleMaxSpeed(&myVehicle);
246  if (neighLead.first == 0) {
247  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighDist, 0, 0));
248  } else {
249  // @todo: what if leader is below safe gap?!!!
250  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
251  }
252  if (leader.first == 0) {
253  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), currentDist, 0, 0));
254  } else {
255  // @todo: what if leader is below safe gap?!!!
256  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), leader.second, leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
257  }
258 
259  thisLaneVSafe = MIN2(thisLaneVSafe, myVehicle.getVehicleType().getMaxSpeed());
260  neighLaneVSafe = MIN2(neighLaneVSafe, myVehicle.getVehicleType().getMaxSpeed());
261  if (thisLaneVSafe - neighLaneVSafe > 5. / 3.6) {
262  // ok, the current lane is faster than the right one...
263  if (myChangeProbability < 0) {
264  myChangeProbability *= pow(0.5, TS);
265  }
266  } else {
267  // ok, the right lane is faster than the current
268  myChangeProbability -= TS * ((neighLaneVSafe - thisLaneVSafe) / (myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle)));
269  }
270 
271  // let's recheck the "Rechtsfahrgebot"
273  vmax -= (double)(5. / 2.6);
274  if (neighLaneVSafe >= vmax) {
275  myChangeProbability -= TS * ((neighLaneVSafe - vmax) / (vmax));
276  }
277 
278  if (myChangeProbability < -2 && neighDist / MAX2((double) .1, myVehicle.getSpeed()) > 20.) { //./MAX2((double) .1, myVehicle.getSpeed())) { // -.1
279  return ret | LCA_RIGHT | LCA_SPEEDGAIN;
280  }
281  // --------
282 
283  return ret;
284 }
285 
286 
287 int
289  int blocked,
290  const std::pair<MSVehicle*, double>& leader,
291  const std::pair<MSVehicle*, double>& neighLead,
292  const std::pair<MSVehicle*, double>& neighFollow,
293  const MSLane& neighLane,
294  const std::vector<MSVehicle::LaneQ>& preb,
295  MSVehicle** lastBlocked,
296  MSVehicle** firstBlocked) {
297  UNUSED_PARAMETER(firstBlocked);
298  MSVehicle::LaneQ curr, best;
299  int bestLaneOffset = 0;
300  double currentDist = 0;
301  double neighDist = 0;
302  double neighExtDist = 0;
303  double currExtDist = 0;
304  int currIdx = 0;
305  MSLane* prebLane = myVehicle.getLane();
306  if (prebLane->getEdge().isInternal()) {
307  // internal edges are not kept inside the bestLanes structure
308  prebLane = prebLane->getLinkCont()[0]->getLane();
309  }
310  for (int p = 0; p < (int) preb.size(); ++p) {
311  if (preb[p].lane == prebLane) {
312  curr = preb[p];
313  bestLaneOffset = curr.bestLaneOffset;
314  currentDist = curr.length;
315  currExtDist = curr.lane->getLength();
316  neighDist = preb[p + 1].length;
317  neighExtDist = preb[p + 1].lane->getLength();
318  best = preb[p + bestLaneOffset];
319  currIdx = p;
320  break;
321  }
322  }
323  // keep information about being a leader/follower
324  int ret = (myOwnState & 0xffff0000);
325 
326  // ?!!!
327  if (leader.first != 0
328  &&
330  &&
331  (leader.first->getLaneChangeModel().getOwnState()&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) {
332 
336  } else {
337  ret |= LCA_AMBACKBLOCKER;
338  myDontBrake = true;
339  }
340  }
341 
342  // process information about the last blocked vehicle
343  // if this vehicle is blocking someone in front, we maybe decelerate to let him in
344  if ((*lastBlocked) != nullptr) {
345  double gap = (*lastBlocked)->getPositionOnLane() - (*lastBlocked)->getVehicleType().getLength() - myVehicle.getPositionOnLane() - myVehicle.getVehicleType().getMinGap();
346  if (gap > 0.1) {
348  if ((*lastBlocked)->getSpeed() < SUMO_const_haltingSpeed) {
350  } else {
351  ret |= LCA_AMBACKBLOCKER;
352  }
353  myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), (double)(gap - 0.1), (*lastBlocked)->getSpeed(), (*lastBlocked)->getCarFollowModel().getMaxDecel()));
354  (*lastBlocked) = nullptr;
355  }
356  return ret;
357  }
358  }
359 
360  // we try to estimate the distance which is necessary to get on a lane
361  // we have to get on in order to keep our route
362  // we assume we need something that depends on our velocity
363  // and compare this with the free space on our wished lane
364  //
365  // if the free space is somehow less than the space we need, we should
366  // definitely try to get to the desired lane
367  //
368  // this rule forces our vehicle to change the lane if a lane changing is necessary soon
370  ? myVehicle.getSpeed() * (double) LOOK_FORWARD_FAR
371  : myVehicle.getSpeed() * (double) LOOK_FORWARD_NEAR;
372  lv += myVehicle.getVehicleType().getLengthWithGap() * (double) 2.;
373 
374 
375  double tdist = currentDist - myVehicle.getPositionOnLane() - best.occupation * (double) JAM_FACTOR2;
376  if (fabs(best.length - curr.length) > MIN2((double) .1, best.lane->getLength()) && bestLaneOffset > 0
377  &&
378  currentDistDisallows(tdist/*currentDist*/, bestLaneOffset, lv)) {
379  informBlocker(msgPass, blocked, LCA_MLEFT, neighLead, neighFollow);
380  if (neighLead.second > 0 && neighLead.second > leader.second) {
381  myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()) - (double) 0.5);
382  }
383 
384  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#1, left
385  // if there is a leader and he wants to change to right (we want to change to left)
386  if (neighLead.first != 0 && (neighLead.first->getLaneChangeModel().getOwnState()&LCA_RIGHT) != 0) {
387  // save at least his length in myLeadingBlockerLength
388  myLeadingBlockerLength = MAX2(neighLead.first->getVehicleType().getLengthWithGap(), myLeadingBlockerLength);
389  // save the left space
390  myLeftSpace = currentDist - myVehicle.getPositionOnLane();
391  }
392  //
393 
394  return ret | LCA_LEFT | LCA_STRATEGIC | LCA_URGENT;
395  }
396 
397  // the opposite lane-changing direction should be rather done, not
398  // the one examined herein
399  // we'll check whether we assume we could change anyhow and get back in time...
400  //
401  // this rule prevents the vehicle from moving in opposite direction of the best lane
402  // unless the way till the end where the vehicle has to be on the best lane
403  // is long enough
404  double maxJam = MAX2(preb[currIdx + 1].occupation, preb[currIdx].occupation);
405  double neighLeftPlace = MAX2((double) 0, neighDist - myVehicle.getPositionOnLane() - maxJam);
406  if (bestLaneOffset <= 0 && (currentDistDisallows(neighLeftPlace, bestLaneOffset - 2, lv))) {
407  // ...we will not change the lane if not
408  return ret | LCA_STAY | LCA_STRATEGIC;
409  }
410 
411 
412  // if the current lane is the best and a lane-changing would cause a situation
413  // of which we assume we will not be able to return to the lane we have to be on...
414  //
415  // this rule prevents the vehicle from leaving the current, best lane when it is
416  // close to this lane's end
417  if (currExtDist > neighExtDist && (neighLeftPlace * 2. < lv/*||currE[currIdx+1].length<currentDist*/)) {
418  // ... let's not change the lane
419  return ret | LCA_STAY | LCA_STRATEGIC;
420  }
421 
422  /*
423  // let's also regard the case where the vehicle is driving on a highway...
424  // in this case, we do not want to get to the dead-end of an on-ramp
425  if(bestLaneOffset==0&&myVehicle.getLane().getMaxSpeed()>80./3.6) {
426  return ret;
427  }
428  */
429 
430 
431  /*
432  // if the current lane is the
433  if(bestLaneOffset==0&&(neighDist==0||curr.seenVehicles2*JAM_FACTOR>=neighExtDist-curr.length)) {
434  return ret;
435  }
436  */
437  // --------
438 
439  // -------- make place on current lane if blocking follower
441  &&
442  (currentDistAllows(neighDist, bestLaneOffset, lv) || neighDist >= currentDist)) {
443 
444  return ret | LCA_LEFT | LCA_COOPERATIVE | LCA_URGENT;
445  }
446  // --------
447 
448  // -------- security checks for krauss
449  // (vsafe fails when gap<0)
450  if ((blocked & LCA_BLOCKED) != 0) {
451  return ret;
452  }
453 
454  // -------- higher speed
455  if ((congested(neighLead.first) && neighLead.second < 20) || predInteraction(leader)) {
456  return ret;
457  }
458  double neighLaneVSafe = neighLane.getVehicleMaxSpeed(&myVehicle);
459  double thisLaneVSafe = myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle);
460  if (neighLead.first == 0) {
461  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighDist, 0, 0)); // !!! warum nicht die Folgesgeschw.?
462  } else {
463  // @todo: what if leader is below safe gap?!!!
464  neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
465  }
466  if (leader.first == 0) {
467  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), currentDist, 0, 0));
468  } else {
469  // @todo: what if leader is below safe gap?!!!
470  thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), leader.second, leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
471  }
472  thisLaneVSafe = MIN2(thisLaneVSafe, myVehicle.getVehicleType().getMaxSpeed());
473  neighLaneVSafe = MIN2(neighLaneVSafe, myVehicle.getVehicleType().getMaxSpeed());
474  if (thisLaneVSafe > neighLaneVSafe) {
475  // this lane is better
476  if (myChangeProbability > 0) {
477  myChangeProbability *= pow(0.5, TS);
478  }
479  } else {
480  // right lane is better
481  myChangeProbability += TS * ((neighLaneVSafe - thisLaneVSafe) / (myVehicle.getLane()->getVehicleMaxSpeed(&myVehicle))); // !!! Fahrzeuggeschw.!
482  }
483  if (myChangeProbability > .2 && neighDist / MAX2((double) .1, myVehicle.getSpeed()) > 20.) { // .1
484  return ret | LCA_LEFT | LCA_SPEEDGAIN | LCA_URGENT;
485  }
486  // --------
487 
488  return ret;
489 }
490 
491 
492 double
493 MSLCM_DK2008::patchSpeed(const double min, const double wanted, const double max, const MSCFModel& cfModel) {
494  int state = myOwnState;
495 
496  // letting vehicles merge in at the end of the lane in case of counter-lane change, step#2
497  double MAGIC_offset = 1.;
498  // if we want to change and have a blocking leader and there is enough room for him in front of us
499  if (myLeadingBlockerLength != 0) {
500  double space = myLeftSpace - myLeadingBlockerLength - MAGIC_offset - myVehicle.getVehicleType().getMinGap();
501  if (space > 0) {
502  // compute speed for decelerating towards a place which allows the blocking leader to merge in in front
503  double safe = cfModel.stopSpeed(&myVehicle, myVehicle.getSpeed(), space);
504  // if we are approaching this place
505  if (safe < wanted) {
506  // return this speed as the speed to use
507  return MAX2(min, safe);
508  }
509  }
510  }
511 
512  // just to make sure to be notified about lane chaning end
513  if (myVehicle.getLane()->getEdge().getLanes().size() == 1 || myVehicle.getLane()->getEdge().isInternal()) {
514  // remove chaning information if on a road with a single lane
515  changed();
516  return wanted;
517  }
518 
519  double nVSafe = wanted;
520  bool gotOne = false;
521  for (std::vector<double>::const_iterator i = myVSafes.begin(); i != myVSafes.end(); ++i) {
522  double v = (*i);
523  if (v >= min && v <= max) {
524  nVSafe = MIN2(v, nVSafe);
525  gotOne = true;
526  }
527  }
528 
529  // check whether the vehicle is blocked
530  if ((state & LCA_WANTS_LANECHANGE) != 0) {
531  if (gotOne && !myDontBrake) {
532  return nVSafe;
533  }
534  // check whether the vehicle maybe has to be swapped with one of
535  // the blocking vehicles
536  if ((state & LCA_BLOCKED) != 0) {
537  if ((state & LCA_BLOCKED_BY_LEADER) != 0) {
538  // if interacting with leader and not too slow
539  return (min + wanted) / (double) 2.0;
540  }
541  if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) {
542  return (max + wanted) / (double) 2.0;
543  }
544  return (min + wanted) / (double) 2.0;
545  }
546  }
547 
548 
549  // decelerate if being a blocking follower
550  // (and does not have to change lanes)
551  if ((state & LCA_AMBLOCKINGFOLLOWER) != 0) {
552  if (fabs(max - myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle)) < 0.001 && min == 0) { // !!! was standing
553  return 0;
554  }
555  return (min + wanted) / (double) 2.0;
556  }
557  if ((state & LCA_AMBACKBLOCKER) != 0) {
558  if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle) && min == 0) { // !!! was standing
559  return min;
560  }
561  }
562  if ((state & LCA_AMBACKBLOCKER_STANDING) != 0) {
563  return min;
564  }
565  // accelerate if being a blocking leader or blocking follower not able to brake
566  // (and does not have to change lanes)
567  if ((state & LCA_AMBLOCKINGLEADER) != 0) {
568  return (max + wanted) / (double) 2.0;
569  }
570  if ((state & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) {
571  if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed(), &myVehicle) && min == 0) { // !!! was standing
572  return wanted;
573  }
574  return (min + wanted) / (double) 2.0;
575  }
576  return wanted;
577 }
578 
579 
580 void*
581 MSLCM_DK2008::inform(void* info, MSVehicle* /*sender*/) {
582  Info* pinfo = (Info*) info;
583  //myOwnState &= 0xffffffff; // reset all bits of MyLCAEnum but only those
584  myOwnState |= pinfo->second;
585  delete pinfo;
586  return (void*) true;
587 }
588 
589 
590 void
592  myOwnState = 0;
595  myLeftSpace = 0;
596  myVSafes.clear();
597  myDontBrake = false;
598 }
599 
600 
601 void
603  int& blocked,
604  int dir,
605  const std::pair<MSVehicle*, double>& neighLead,
606  const std::pair<MSVehicle*, double>& neighFollow) {
607  if ((blocked & LCA_BLOCKED_BY_FOLLOWER) != 0) {
608  assert(neighFollow.first != 0);
609  MSVehicle* nv = neighFollow.first;
610  double decelGap =
611  neighFollow.second
612  + SPEED2DIST(myVehicle.getSpeed()) * (double) 2.0
613  - MAX2(nv->getSpeed() - (double) ACCEL2DIST(nv->getCarFollowModel().getMaxDecel()) * (double) 2.0, (double) 0);
614  if (neighFollow.second > 0 && decelGap > 0 && decelGap >= nv->getCarFollowModel().getSecureGap(nv, &myVehicle,
616  double vsafe = myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighFollow.second, neighFollow.first->getSpeed(), neighFollow.first->getCarFollowModel().getMaxDecel());
617  msgPass.informNeighFollower(new Info(vsafe, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle);
618  } else {
619  double vsafe = neighFollow.second <= 0 ? 0 : myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighFollow.second, neighFollow.first->getSpeed(), neighFollow.first->getCarFollowModel().getMaxDecel());
621  }
622  }
623  if ((blocked & LCA_BLOCKED_BY_LEADER) != 0) {
624  if (neighLead.first != 0 && neighLead.second > 0) {
625  msgPass.informNeighLeader(new Info(0, dir | LCA_AMBLOCKINGLEADER), &myVehicle);
626  }
627  }
628 }
629 
630 
631 void
634  myOwnState = 0;
636  myLeftSpace = 0;
637  myVSafes.clear();
638  myDontBrake = false;
639  // truncate myChangeProbability to work around numerical instability between different builds
640  myChangeProbability = ceil(myChangeProbability * 100000.0) * 0.00001;
641 }
642 
643 
644 /****************************************************************************/
645 
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:31
MSLCM_DK2008::inform
virtual void * inform(void *info, MSVehicle *sender)
Definition: MSLCM_DK2008.cpp:581
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
SPEED2DIST
#define SPEED2DIST(x)
Definition: SUMOTime.h:46
MSLCM_DK2008::currentDistDisallows
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
Definition: MSLCM_DK2008.h:128
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
MSLCM_DK2008::changed
virtual void changed()
Definition: MSLCM_DK2008.cpp:591
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
MSLCM_DK2008::myLeadingBlockerLength
double myLeadingBlockerLength
Definition: MSLCM_DK2008.h:142
MSNet.h
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
LCA_LEFT
@ LCA_LEFT
Wants go to the left.
Definition: SUMOXMLDefinitions.h:1226
MSCFModel::maxNextSpeed
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:238
MSLCM_DK2008::myChangeProbability
double myChangeProbability
Definition: MSLCM_DK2008.h:140
MSAbstractLaneChangeModel::MSLCMessager
A class responsible for exchanging messages between cars involved in lane-change interaction.
Definition: MSAbstractLaneChangeModel.h:51
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
MSVehicle::LaneQ
A structure representing the best lanes for continuing the current route starting at 'lane'.
Definition: MSVehicle.h:810
LCA_SPEEDGAIN
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
Definition: SUMOXMLDefinitions.h:1234
JAM_FACTOR2
#define JAM_FACTOR2
Definition: MSLCM_DK2008.cpp:46
LCA_URGENT
@ LCA_URGENT
The action is urgent (to be defined by lc-model)
Definition: SUMOXMLDefinitions.h:1240
LCA_BLOCKED_BY_LEADER
@ LCA_BLOCKED_BY_LEADER
blocked by leader
Definition: SUMOXMLDefinitions.h:1272
MSEdge.h
MSVehicle::getCarFollowModel
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:893
SUMO_const_haltingSpeed
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:60
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
MSLCM_DK2008::prepareStep
virtual void prepareStep()
Definition: MSLCM_DK2008.cpp:632
ACCEL2DIST
#define ACCEL2DIST(x)
Definition: SUMOTime.h:50
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
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
MSAbstractLaneChangeModel::prepareStep
virtual void prepareStep()
Definition: MSAbstractLaneChangeModel.cpp:889
MSLCM_DK2008::patchSpeed
virtual 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.
Definition: MSLCM_DK2008.cpp:493
MSLCM_DK2008::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_DK2008.cpp:62
LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
@ LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
Definition: SUMOXMLDefinitions.h:1291
MSLCM_DK2008::myLeftSpace
double myLeftSpace
Definition: MSLCM_DK2008.h:143
MSAbstractLaneChangeModel::congested
virtual bool congested(const MSVehicle *const neighLeader)
Definition: MSAbstractLaneChangeModel.cpp:245
MSLane::getLength
double getLength() const
Returns the lane's length.
Definition: MSLane.h:540
MSVehicle::LaneQ::lane
MSLane * lane
The described lane.
Definition: MSVehicle.h:812
MSLCM_DK2008::wantsChangeToLeft
virtual int wantsChangeToLeft(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 to left This method gets the information about ...
Definition: MSLCM_DK2008.cpp:288
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
MSLCM_DK2008::myDontBrake
bool myDontBrake
Definition: MSLCM_DK2008.h:146
MSBaseVehicle::getVehicleType
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:123
MSLane::getLinkCont
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:2110
LOOK_FORWARD_SPEED_DIVIDER
#define LOOK_FORWARD_SPEED_DIVIDER
Definition: MSLCM_DK2008.cpp:38
MSLCM_DK2008::wantsChangeToRight
virtual int wantsChangeToRight(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 to right This method gets the information about...
Definition: MSLCM_DK2008.cpp:81
LCA_WANTS_LANECHANGE
@ LCA_WANTS_LANECHANGE
lane can change
Definition: SUMOXMLDefinitions.h:1264
MSLCM_DK2008::MSLCM_DK2008
MSLCM_DK2008(MSVehicle &v)
Definition: MSLCM_DK2008.cpp:52
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
LOOK_FORWARD_FAR
#define LOOK_FORWARD_FAR
Definition: MSLCM_DK2008.cpp:40
MSLCM_DK2008::currentDistAllows
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
Definition: MSLCM_DK2008.h:131
MSLCM_DK2008::myVSafes
std::vector< double > myVSafes
Definition: MSLCM_DK2008.h:145
LCA_RIGHT
@ LCA_RIGHT
Wants go to the right.
Definition: SUMOXMLDefinitions.h:1228
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
LOOK_FORWARD_NEAR
#define LOOK_FORWARD_NEAR
Definition: MSLCM_DK2008.cpp:41
LCA_AMBACKBLOCKER_STANDING
@ LCA_AMBACKBLOCKER_STANDING
Definition: SUMOXMLDefinitions.h:1297
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::predInteraction
virtual bool predInteraction(const std::pair< MSVehicle *, double > &leader)
Definition: MSAbstractLaneChangeModel.cpp:265
MSAbstractLaneChangeModel::myOwnState
int myOwnState
The current state of the vehicle.
Definition: MSAbstractLaneChangeModel.h:592
MSLCM_DK2008::Info
std::pair< double, int > Info
Definition: MSLCM_DK2008.h:135
MSLCM_DK2008::informBlocker
void informBlocker(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int &blocked, int dir, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow)
Definition: MSLCM_DK2008.cpp:602
MSEdge::getLanes
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:167
MSLCM_DK2008.h
MSVehicleType::getMaxSpeed
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
Definition: MSVehicleType.h:161
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:56
MSLCM_DK2008::amBlockingFollowerPlusNB
bool amBlockingFollowerPlusNB()
Definition: MSLCM_DK2008.h:125
config.h
LCA_BLOCKED_BY_FOLLOWER
@ LCA_BLOCKED_BY_FOLLOWER
blocker by follower
Definition: SUMOXMLDefinitions.h:1274
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
MSLane.h
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
LCA_AMBACKBLOCKER
@ LCA_AMBACKBLOCKER
Definition: SUMOXMLDefinitions.h:1296
MSLane::getSpeedLimit
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:532
LCA_MRIGHT
@ LCA_MRIGHT
Definition: SUMOXMLDefinitions.h:1288
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
LCM_DK2008
@ LCM_DK2008
Definition: SUMOXMLDefinitions.h:1304
MSLCM_DK2008::~MSLCM_DK2008
virtual ~MSLCM_DK2008()
Definition: MSLCM_DK2008.cpp:57
LCA_AMBLOCKINGFOLLOWER
@ LCA_AMBLOCKINGFOLLOWER
Definition: SUMOXMLDefinitions.h:1287
LCA_BLOCKED
@ LCA_BLOCKED
blocked in all directions
Definition: SUMOXMLDefinitions.h:1276
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79