44 #define LOOK_FORWARD (double)10. 46 #define JAM_FACTOR (double)1. 48 #define LCA_RIGHT_IMPATIENCE (double)-1. 49 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27. 51 #define LOOK_AHEAD_MIN_SPEED 0.0 52 #define LOOK_AHEAD_SPEED_MEMORY 0.9 54 #define HELP_DECEL_FACTOR (double)1.0 56 #define HELP_OVERTAKE (double)(10.0 / 3.6) 57 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 60 #define OVERTAKE_RIGHT_THRESHOLD (double)(5/3.6) 62 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 63 #define URGENCY (double)2.0 64 #define OPPOSITE_URGENCY (double)5.0 66 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 67 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 69 #define ROUNDABOUT_DIST_FACTOR (double)10.0 // Must be >=1.0, serves an alternative way of decreasing sense lc-urgency by multiplying the distance along the next roundabout 71 #define KEEP_RIGHT_HEADWAY (double)2.0 72 #define MAX_ONRAMP_LENGTH (double)200. 73 #define TURN_LANE_DIST (double)200.0 // the distance at which a lane leading elsewhere is considered to be a turn-lane that must be avoided 75 #define LC_RESOLUTION_SPEED_LAT (double)0.5 // the lateral speed (in m/s) for a standing vehicle which was unable to finish a continuous LC in time (in case mySpeedLatStanding==0), see #3771 76 #define LC_ASSUMED_DECEL (double)1.0 // the minimal constant deceleration assumed to estimate the duration of a continuous lane-change at its initiation. 78 #define REACT_TO_STOPPED_DISTANCE 100 93 #define DEBUG_COND (myVehicle.isSelected()) 101 mySpeedGainProbability(0),
102 myKeepRightProbability(0),
103 myLeadingBlockerLength(0),
117 #ifdef DEBUG_CONSTRUCTOR 153 const std::pair<MSVehicle*, double>& leader,
154 const std::pair<MSVehicle*, double>& neighLead,
155 const std::pair<MSVehicle*, double>& neighFollow,
157 const std::vector<MSVehicle::LaneQ>& preb,
161 #ifdef DEBUG_WANTS_CHANGE 163 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 170 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
175 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
177 #ifdef DEBUG_WANTS_CHANGE 190 #ifdef DEBUG_PATCH_SPEED 192 std::cout <<
"\nPATCH_SPEED\n" 199 <<
" wanted=" << wanted
206 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
208 #ifdef DEBUG_PATCH_SPEED 210 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
223 #ifdef DEBUG_PATCH_SPEED 230 <<
" wanted=" << wanted << std::endl;
235 double MAGIC_offset = 1.;
239 #ifdef DEBUG_PATCH_SPEED 250 #ifdef DEBUG_PATCH_SPEED 252 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
255 return MAX2(min, safe);
260 double nVSafe = wanted;
274 nVSafe =
MIN2(v * coopWeight + (1 - coopWeight) * wanted, nVSafe);
276 #ifdef DEBUG_PATCH_SPEED 283 #ifdef DEBUG_PATCH_SPEED 285 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
289 #ifdef DEBUG_PATCH_SPEED 291 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
299 #ifdef DEBUG_PATCH_SPEED 312 #ifdef DEBUG_PATCH_SPEED 317 return (max + wanted) / (double) 2.0;
321 #ifdef DEBUG_PATCH_SPEED 327 return (
MAX2(0., min) + wanted) / (double) 2.0;
333 #ifdef DEBUG_PATCH_SPEED 338 return (max + wanted) / (double) 2.0;
379 #ifdef DEBUG_PATCH_SPEED 384 return (max + wanted) / (double) 2.0;
388 #ifdef DEBUG_PATCH_SPEED 416 #ifdef DEBUG_INFORMED 420 <<
" informedBy=" << sender->
getID()
421 <<
" info=" << pinfo->second
422 <<
" vSafe=" << pinfo->first
434 double overtakeDist = (gap
439 return MAX2(overtakeDist, 0.);
447 const std::pair<MSVehicle*, double>& neighLead,
448 double remainingSeconds) {
457 #ifdef DEBUG_INFORMER 459 std::cout <<
"\nINFORM_LEADER" 464 const MSVehicle*
const nv = neighLead.first;
472 neighNextGap = neighLead.second +
SPEED2DIST(neighNextSpeed - plannedSpeed);
477 #ifdef DEBUG_INFORMER 479 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 486 const double dv = plannedSpeed - nv->
getSpeed();
489 overtakeTime = overtakeDist / dv;
492 overtakeTime = remainingSeconds + 1;
495 #ifdef DEBUG_INFORMER 498 <<
"\nnv = " << nv->
getID()
499 <<
"\nplannedSpeed = " << plannedSpeed
500 <<
"\nleaderSpeed = " << nv->
getSpeed()
502 <<
"\nremainingSeconds = " << remainingSeconds
503 <<
"\novertakeDist = " << overtakeDist
504 <<
"\novertakeTime = " << overtakeTime
519 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
524 const double targetSpeed =
MAX2(
533 #ifdef DEBUG_INFORMER 536 <<
" cannot overtake leader nv=" << nv->
getID()
540 <<
" overtakeDist=" << overtakeDist
541 <<
" overtakeTime=" << overtakeTime
542 <<
" remainingSeconds=" << remainingSeconds
543 <<
" currentGap=" << neighLead.second
545 <<
" neighNextSpeed=" << neighNextSpeed
546 <<
" neighNextGap=" << neighNextGap
547 <<
" targetSpeed=" << targetSpeed
548 <<
" nextSpeed=" << nextSpeed
556 #ifdef DEBUG_INFORMER 559 <<
" cannot overtake fast leader nv=" << nv->
getID()
563 <<
" overtakeDist=" << overtakeDist
565 <<
" overtakeTime=" << overtakeTime
566 <<
" remainingSeconds=" << remainingSeconds
567 <<
" currentGap=" << neighLead.second
568 <<
" targetSpeed=" << targetSpeed
577 #ifdef DEBUG_INFORMER 580 <<
" wants to overtake leader nv=" << nv->
getID()
582 <<
" overtakeDist=" << overtakeDist
583 <<
" remainingSeconds=" << remainingSeconds
584 <<
" overtakeTime=" << overtakeTime
585 <<
" currentGap=" << neighLead.second
595 const double targetSpeed =
MAX2(
599 #ifdef DEBUG_INFORMER 601 std::cout <<
" not blocked by leader nv=" << nv->
getID()
603 <<
" gap=" << neighLead.second
604 <<
" neighNextSpeed=" << neighNextSpeed
605 <<
" neighNextGap=" << neighNextGap
607 <<
" targetSpeed=" << targetSpeed
611 return MIN2(targetSpeed, plannedSpeed);
619 const std::pair<MSVehicle*, double>& neighFollow,
620 double remainingSeconds,
621 double plannedSpeed) {
626 #ifdef DEBUG_INFORMER 628 std::cout <<
"\nINFORM_FOLLOWER" 634 #ifdef DEBUG_INFORMER 636 std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 644 if ((neededGap - neighFollow.second) / remainingSeconds < (
MAX2(plannedSpeed, 0.) - nv->
getSpeed())) {
645 #ifdef DEBUG_INFORMER 647 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help." <<
"\nneededGap = " << neededGap <<
"\n";
667 double neighNewSpeed;
669 double neighNewSpeed1s;
679 dv = plannedSpeed - neighNewSpeed1s;
686 decelGap = neighFollow.second + dv;
693 neighNewSpeed1s = nv->
getSpeed() - helpDecel;
705 #ifdef DEBUG_INFORMER 709 <<
" plannedSpeed=" << plannedSpeed
710 <<
" threshold=" << onRampThreshold
711 <<
" neighNewSpeed=" << neighNewSpeed
712 <<
" neighNewSpeed1s=" << neighNewSpeed1s
714 <<
" gap=" << neighFollow.second
715 <<
" decelGap=" << decelGap
716 <<
" secureGap=" << secureGap
723 && neighNewSpeed1s < onRampThreshold) {
727 if (decelGap > 0 && decelGap >= secureGap) {
735 double vsafe, vsafe1;
744 assert(vsafe <= vsafe1);
755 #ifdef DEBUG_INFORMER 757 std::cout <<
"nextGap=" << nextGap <<
" (without help decel) \n";
765 MAX2(0., plannedSpeed),
773 nv->
getSpeed(), plannedAccel, -decel2,
783 MAX2(0., plannedSpeed),
788 #ifdef DEBUG_INFORMER 790 std::cout <<
"nextGap=" << nextGap
791 <<
" (with vsafe1 and help decel) \nvsafe1=" << vsafe1
792 <<
" vsafe=" << vsafe
801 if (nextGap < nextSecureGap) {
803 vsafe = neighNewSpeed;
806 #ifdef DEBUG_INFORMER 808 std::cout <<
"nextGap=" << nextGap
809 <<
" minNextSecureGap=" << nextSecureGap
810 <<
" vsafe=" << vsafe <<
"\n";
818 #ifdef DEBUG_INFORMER 820 std::cout <<
" wants to cut in before nv=" << nv->
getID()
821 <<
" vsafe1=" << vsafe1 <<
" vsafe=" << vsafe
847 #ifdef DEBUG_INFORMER 849 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
856 #ifdef DEBUG_INFORMER 858 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
877 #ifdef DEBUG_INFORMER 881 std::cout <<
" wants right follower to slow down a bit\n";
888 #ifdef DEBUG_INFORMER 891 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
913 if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) {
914 #ifdef DEBUG_INFORMER 916 std::cout <<
" wants to cut in before follower nv=" << nv->
getID() <<
" (eventually)\n";
929 #ifdef DEBUG_INFORMER 933 <<
" informs follower " << nv->
getID()
934 <<
" vhelp=" << vhelp
943 const double needDV = overtakeDist / remainingSeconds;
947 #ifdef DEBUG_INFORMER 951 <<
" wants to be overtaken by=" << nv->
getID()
952 <<
" overtakeDist=" << overtakeDist
954 <<
" vhelp=" << vhelp
955 <<
" needDV=" << needDV
964 double vsafe, vsafe1;
978 double anticipationTime = 1.;
989 if (anticipatedGap > secureGap) {
996 if (anticipatedGap < secureGap) {
1007 #ifdef DEBUG_INFORMER 1009 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
1053 const std::pair<MSVehicle*, double>& leader,
1054 const std::pair<MSVehicle*, double>& neighLead,
1055 const std::pair<MSVehicle*, double>& neighFollow,
1057 const std::vector<MSVehicle::LaneQ>& preb,
1060 assert(laneOffset == 1 || laneOffset == -1);
1064 int bestLaneOffset = 0;
1069 double currentDist = 0;
1070 double neighDist = 0;
1079 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1080 for (
int p = 0; p < (int) preb.size(); ++p) {
1081 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1082 assert(p + prebOffset < (
int)preb.size());
1084 neigh = preb[p + prebOffset];
1085 currentDist = curr.
length;
1086 neighDist = neigh.
length;
1087 bestLaneOffset = curr.bestLaneOffset;
1088 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1089 #ifdef DEBUG_WANTS_CHANGE 1093 <<
" bestLaneOffsetOld=" << bestLaneOffset
1094 <<
" bestLaneOffsetNew=" << laneOffset
1098 bestLaneOffset = prebOffset;
1100 best = preb[p + bestLaneOffset];
1106 const bool right = (laneOffset == -1);
1108 neigh = preb[preb.size() - 1];
1111 bestLaneOffset = -1;
1113 neighDist = neigh.
length;
1114 currentDist = curr.
length;
1116 double driveToNextStop = -std::numeric_limits<double>::max();
1124 #ifdef DEBUG_WANTS_CHANGE 1129 <<
" stopPos=" << stopPos
1130 <<
" currentDist=" << currentDist
1131 <<
" neighDist=" << neighDist
1135 currentDist =
MAX2(currentDist, stopPos);
1136 neighDist =
MAX2(neighDist, stopPos);
1142 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1148 if (lastBlocked != firstBlocked) {
1152 #ifdef DEBUG_WANTS_CHANGE 1161 <<
" leaderGap=" << leader.second
1163 <<
" neighLeadGap=" << neighLead.second
1165 <<
" neighFollowGap=" << neighFollow.second
1188 assert(memoryFactor > 0.);
1196 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped() && leader.second < (currentDist - posOnLane)) {
1201 + leader.first->getVehicleType().getLengthWithGap()
1203 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped() && neighLead.second < (currentDist - posOnLane)) {
1206 + neighLead.first->getVehicleType().getLengthWithGap()
1207 + neighLead.second);
1222 currentDist += roundaboutBonus;
1223 neighDist += roundaboutBonus;
1227 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1228 const double neighLeftPlace =
MAX2((
double) 0, neighDist - posOnLane - maxJam);
1231 double thisLaneVSafe = vMax;
1237 #ifdef DEBUG_WANTS_CHANGE 1242 <<
" laDist=" << laDist
1243 <<
" currentDist=" << currentDist
1244 <<
" usableDist=" << usableDist
1245 <<
" bestLaneOffset=" << bestLaneOffset
1247 <<
" best.length=" << best.
length 1248 <<
"\n roundaboutBonus=" << roundaboutBonus
1249 <<
" maxJam=" << maxJam
1250 <<
" neighDist=" << neighDist
1251 <<
" neighLeftPlace=" << neighLeftPlace
1256 bool changeLeftToAvoidOvertakeRight =
false;
1263 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1275 if (vSafeFollow >= vMaxDecel) {
1276 vSafe = vSafeFollow;
1278 vSafe =
MAX2(vMaxDecel, vStayBehind);
1283 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1286 const double deltaGapFuture = deltaV * 8;
1289 if (vSafeFuture < vSafe) {
1290 const double relativeGain = deltaV /
MAX2(vMax,
1293 changeLeftToAvoidOvertakeRight =
true;
1295 #ifdef DEBUG_WANTS_CHANGE 1298 <<
" avoid overtaking on the right nv=" << nv->
getID()
1299 <<
" deltaV=" << deltaV
1308 const double overtakeDist = (leader.first == 0 ? -1 :
1312 &&
MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1314 && (!checkOverTakeRight || !right)
1315 && (neighLead.first == 0 || !neighLead.first->isStopped()
1317 || neighLead.second > overtakeDist)) {
1320 #ifdef DEBUG_WANTS_CHANGE 1322 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" overtake stopped leader=" << leader.first->getID()
1323 <<
" overtakeDist=" << overtakeDist
1324 <<
" remaining=" <<
MIN2(neighDist, currentDist) - posOnLane
1329 }
else if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1336 #ifdef DEBUG_WANTS_CHANGE 1338 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1342 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1347 #ifdef DEBUG_WANTS_CHANGE 1349 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1353 }
else if (bestLaneOffset == 0
1354 && (leader.first == 0 || !leader.first->isStopped())
1356 && roundaboutBonus == 0
1362 #ifdef DEBUG_WANTS_CHANGE 1364 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1371 #ifdef DEBUG_WANTS_CHANGE 1379 if ((ret & lcaCounter) != 0) {
1383 #ifdef DEBUG_WANTS_CHANGE 1385 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
1396 if (changeToBest && abs(bestLaneOffset) > 1) {
1399 #ifdef DEBUG_WANTS_CHANGE 1401 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1409 if (*firstBlocked != neighLead.first) {
1413 const int remainingLanes =
MAX2(1, abs(bestLaneOffset));
1415 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1419 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1424 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1427 #ifdef DEBUG_WANTS_CHANGE 1432 <<
" remainingSeconds=" << remainingSeconds
1433 <<
" plannedSpeed=" << plannedSpeed
1441 const double inconvenience =
MIN2((
double)1.0, (laneOffset < 0
1448 if (roundaboutBonus > 0) {
1450 #ifdef DEBUG_WANTS_CHANGE 1454 <<
" roundaboutBonus=" << roundaboutBonus
1484 #ifdef DEBUG_WANTS_CHANGE 1486 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1506 && (!speedGainInconvenient)
1508 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1511 #ifdef DEBUG_COOPERATE 1515 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1517 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1546 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1547 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1549 if (acceleratingLeader) {
1556 if (neighLead.first == 0) {
1560 &
myVehicle, correctedSpeed, neighLead.second, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1562 if (leader.first == 0) {
1566 &
myVehicle, correctedSpeed, leader.second, leader.first->
getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1569 if (neighLead.first == 0) {
1573 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel(),
true));
1575 if (leader.first == 0) {
1579 leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel(),
true));
1589 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1592 #ifdef DEBUG_WANTS_CHANGE 1596 <<
" currentDist=" << currentDist
1597 <<
" neighDist=" << neighDist
1598 <<
" thisVSafe=" << thisLaneVSafe
1599 <<
" neighVSafe=" << neighLaneVSafe
1600 <<
" relGain=" <<
toString(relativeGain, 8)
1607 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1624 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1633 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1634 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1635 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1637 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1638 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1641 if (checkOverTakeRight && leader.first != 0
1642 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1643 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1644 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1645 const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1654 #ifdef DEBUG_WANTS_CHANGE 1659 <<
" neighDist=" << neighDist
1661 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1663 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1664 <<
" acceptanceTime=" << acceptanceTime
1665 <<
" fullSpeedGap=" << fullSpeedGap
1666 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1667 <<
" dProb=" << deltaProb
1680 #ifdef DEBUG_WANTS_CHANGE 1686 <<
" thisLaneVSafe=" << thisLaneVSafe
1687 <<
" neighLaneVSafe=" << neighLaneVSafe
1688 <<
" relativeGain=" << relativeGain
1689 <<
" blocked=" << blocked
1703 if (thisLaneVSafe > neighLaneVSafe) {
1708 }
else if (thisLaneVSafe == neighLaneVSafe) {
1726 #ifdef DEBUG_WANTS_CHANGE 1732 <<
" thisLaneVSafe=" << thisLaneVSafe
1733 <<
" neighLaneVSafe=" << neighLaneVSafe
1734 <<
" relativeGain=" << relativeGain
1735 <<
" blocked=" << blocked
1741 && (relativeGain >
NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1751 && relativeGain >= 0
1752 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1759 #ifdef DEBUG_WANTS_CHANGE 1765 <<
" thisLaneVSafe=" << thisLaneVSafe
1766 <<
" neighLaneVSafe=" << neighLaneVSafe
1782 int roundaboutJunctionsAhead = 0;
1783 bool enteredRoundabout =
false;
1789 if (lane ==
nullptr) {
1794 #ifdef DEBUG_WANTS_CHANGE 1796 std::cout <<
" noBonus: inner does not continue (lane=" << lane->
getID() <<
")\n";
1803 #ifdef DEBUG_WANTS_CHANGE 1805 std::cout <<
" noBonus: seen=" << seen <<
" (lane=" << lane->
getID() <<
")\n";
1812 enteredRoundabout =
true;
1814 roundaboutJunctionsAhead++;
1816 }
else if (enteredRoundabout) {
1823 if (roundaboutJunctionsAhead < 2) {
1829 double occupancyOuter = 0;
1830 double occupancyInner = 0;
1831 double distanceInRoundabout = 0;
1832 MSLane* prevNormal =
nullptr;
1833 MSLane* prevInner =
nullptr;
1834 enteredRoundabout =
false;
1837 if (lane ==
nullptr) {
1841 enteredRoundabout =
true;
1842 }
else if (enteredRoundabout) {
1847 if (prevNormal !=
nullptr) {
1849 if (link->getLane() == lane) {
1850 via = link->getViaLane();
1854 if (enteredRoundabout) {
1855 distanceInRoundabout += lane->
getLength();
1856 if (via !=
nullptr) {
1857 distanceInRoundabout += via->
getLength();
1866 std::cout <<
" lane=" << lane->
getID() <<
" occ=" << lane->
getBruttoVehLenSum() <<
" discount=" << upstreamDiscount <<
" outer=" << occupancyOuter <<
"\n";
1868 if (via !=
nullptr) {
1871 std::cout <<
" via=" << via->
getID() <<
" occ=" << via->
getBruttoVehLenSum() <<
" outer=" << occupancyOuter <<
"\n";
1878 std::cout <<
" inner=" << innerLane->
getID() <<
" occ=" << innerLane->
getBruttoVehLenSum() <<
" discount=" << upstreamDiscount <<
" inner=" << occupancyInner <<
"\n";
1880 if (prevInner !=
nullptr) {
1882 if (link->getLane() == innerLane && link->getViaLane() !=
nullptr) {
1883 occupancyInner += link->getViaLane()->getBruttoVehLenSum();
1885 std::cout <<
" innerVia=" << link->getViaLane()->getID() <<
" occ=" << link->getViaLane()->getBruttoVehLenSum() <<
" inner=" << occupancyInner <<
"\n";
1890 prevInner = innerLane;
1894 #ifdef DEBUG_WANTS_CHANGE 1896 std::cout <<
" distanceInRoundabout=" << distanceInRoundabout
1897 <<
" roundaboutJunctionsAhead=" << roundaboutJunctionsAhead
1898 <<
" occupancyInner=" << occupancyInner
1899 <<
" occupancyOuter=" << occupancyOuter
1904 const double maxOccupancy =
MAX2(occupancyInner, occupancyOuter);
1905 if (maxOccupancy == 0) {
1910 const double bonus = roundaboutJunctionsAhead * 7.5;
1911 const double relativeJam = (occupancyOuter - occupancyInner + bonus) / (maxOccupancy + bonus);
1913 const double jamFactor =
MAX2(0.0, relativeJam);
1915 #ifdef DEBUG_WANTS_CHANGE 1917 std::cout <<
" relativeJam=" << relativeJam
1918 <<
" jamFactor=" << jamFactor
1919 <<
" distanceBonus=" << result
1930 if ((*blocked) !=
nullptr) {
1932 #ifdef DEBUG_SLOW_DOWN 1956 (*blocked)->getCarFollowModel().getMaxDecel()));
1959 #ifdef DEBUG_SLOW_DOWN 1963 <<
" slowing down for" 1985 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2001 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2013 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2019 <<
" potential=" << potential
2032 #ifdef DEBUG_WANTS_CHANGE 2034 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
2040 if (leader.first != 0) {
2042 v =
MIN2(v, stopSpeed);
2043 #ifdef DEBUG_WANTS_CHANGE 2045 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
2066 return MAX2(-speedBound,
MIN2(speedBound,
2082 return myOppositeParam <= 0 ? std::numeric_limits<double>::max() : 1 /
myOppositeParam;
double myLeadingBlockerLength
double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
Called to adapt the speed in order to allow a lane change. It uses information on LC-related desired ...
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double maximumSafeFollowSpeed(double gap, double egoSpeed, double predSpeed, double predMaxDecel, bool onInsertion=false) const
Returns the maximum safe velocity for following the given leader.
double getAssumedDecelForLaneChangeDuration() const
Returns a deceleration value which is used for the estimation of the duration of a lane change...
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i...
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
MSLCM_LC2013(MSVehicle &v)
The action is due to the default of keeping right "Rechtsfahrgebot".
The action is done to help someone else.
double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
double getRoundaboutDistBonus(const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, const MSVehicle::LaneQ &best)
Computes the artificial bonus distance for roundabout lanes this additional distance reduces the sens...
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
MSLane * getLane() const
Returns the lane the vehicle is on.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
std::mt19937 * getRNG() const
int gPrecision
the precision for floating point outputs
double myKeepRightProbability
The base class for an intersection.
#define KEEP_RIGHT_ACCEPTANCE
The car-following model abstraction.
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
double getPositionOnLane() const
Get the vehicle's position along the lane.
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
double myChangeProbThresholdLeft
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
#define MAX_ONRAMP_LENGTH
int getBestLaneOffset() const
int _wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
helper function for doing the actual work
void initDerivedParameters()
init cached parameters derived directly from model parameters
bool isRoundabout() const
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
double getLength() const
Returns the lane's length.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
double myMaxSpeedLatStanding
double getRightSideOnLane() const
Get the vehicle's lateral position on the lane:
const std::string & getID() const
Returns the id.
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
double computeSpeedLat(double latDist, double &maneuverDist)
decides the next lateral speed (for continuous lane changing)
double length
The overall length which may be driven when using this lane without a lane change.
const MSJunction * getToJunction() const
The action is due to the wish to be faster (tactical lc)
#define UNUSED_PARAMETER(x)
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
bool hasLaneChanger() const
#define ROUNDABOUT_DIST_FACTOR
MSAbstractLaneChangeModel & getLaneChangeModel()
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation...
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Needs to stay on the current lane.
const LaneChangeModel myModel
the type of this model
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
bool debugVehicle() const
whether the current vehicles shall be debugged
A class responsible for exchanging messages between cars involved in lane-change interaction.
static double overtakeDistance(const MSVehicle *follower, const MSVehicle *leader, const double gap, double followerSpeed=INVALID_SPEED, double leaderSpeed=INVALID_SPEED)
MSLane * lane
The described lane.
double getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points...
double mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial ...
void informFollower(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighFollow, double remainingSeconds, double plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
blocked in all directions
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
The action is urgent (to be defined by lc-model)
virtual double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
static MSPModel * getModel()
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
#define CUT_IN_LEFT_SPEED_THRESHOLD
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
double myMaxSpeedLatFactor
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
#define LOOK_AHEAD_SPEED_MEMORY
const double myExperimentalParam1
#define REACT_TO_STOPPED_DISTANCE
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
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...
const ConstMSEdgeVector & getIncoming() const
#define RELGAIN_NORMALIZATION_MIN_SPEED
The action is needed to follow the route (navigational lc)
virtual double getSpeedAfterMaxDecel(double v) const
Returns the velocity after maximum deceleration.
const double myOvertakeRightParam
double getImpatience() const
Returns this vehicles impatience.
A structure representing the best lanes for continuing the current route starting at 'lane'...
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0 ...
double getMinGap() const
Get the free space in front of vehicles of this class.
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
int myOwnState
The current state of the vehicle.
double maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
bool isInternal() const
return whether this edge is an internal edge
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()...
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
const MSLane * lane
The lane to stop at.
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
const ConstMSEdgeVector & getOutgoing() const
static double gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1=0, double a2=0, const double maxV1=std::numeric_limits< double >::max(), const double maxV2=std::numeric_limits< double >::max())
return the resulting gap if, starting with gap currentGap, two vehicles continue with constant accele...
std::pair< const MSPerson *, double > PersonDist
double myChangeProbThresholdRight
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
Influencer & getInfluencer()
Returns the velocity/lane influencer.
LaneChangeAction
The state of a vehicle's lane-change behavior.
void adaptSpeedToPedestrians(const MSLane *lane, double &v)
react to pedestrians on the given lane
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key ...
std::vector< MSLane * > bestContinuations
int & getCanceledState(const int dir)
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
double myCooperativeParam
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key ...
double getLength() const
Get vehicle's length [m].
virtual void prepareStep()
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
virtual void saveBlockerLength(double length)
reserve space at the end of the lane to avoid dead locks
virtual double computeSpeedLat(double latDist, double &maneuverDist)
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
#define LC_RESOLUTION_SPEED_LAT
The action is due to a TraCI request.
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
static bool gSemiImplicitEulerUpdate
bool amBlockingFollowerPlusNB()
double informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighLead, double remainingSeconds)
bool isStopped() const
Returns whether the vehicle is at a stop.
#define LOOK_AHEAD_MIN_SPEED
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
#define LCA_RIGHT_IMPATIENCE
double getSpeed() const
Returns the vehicle's current speed.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
public emergency vehicles
void * inform(void *info, MSVehicle *sender)
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)
const std::string & getID() const
Returns the name of the vehicle.
Representation of a lane in the micro simulation.
const MSCFModel & myCarFollowModel
The vehicle's car following model.
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Interface for lane-change models.
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) ...
bool isAccelLane() const
return whether this lane is an acceleration lane
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
#define HELP_DECEL_FACTOR
double getOppositeSafetyFactor() const
return factor for modifying the safety constraints for opposite-diretction overtaking of the car-foll...