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 68 #define ROUNDABOUT_DIST_BONUS (double)100.0 // valence (distance) for to faked per roundabout edge in front (inducing inner lane usage in roundabouts by decreasing sense of lc-urgency) 70 #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 ROUNDABOUT_DIST_TRESH (double)10.0 // roundabout distances below ROUNDABOUT_DIST_TRESH are not multiplied by ROUNDABOUT_DIST_FACTOR 73 #define KEEP_RIGHT_HEADWAY (double)2.0 74 #define MAX_ONRAMP_LENGTH (double)200. 75 #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 77 #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 78 #define LC_ASSUMED_DECEL (double)1.0 // the minimal constant deceleration assumed to estimate the duration of a continuous lane-change at its initiation. 80 #define REACT_TO_STOPPED_DISTANCE 100 95 #define DEBUG_COND (myVehicle.isSelected()) 103 mySpeedGainProbability(0),
104 myKeepRightProbability(0),
105 myLeadingBlockerLength(0),
118 #ifdef DEBUG_CONSTRUCTOR 154 const std::pair<MSVehicle*, double>& leader,
155 const std::pair<MSVehicle*, double>& neighLead,
156 const std::pair<MSVehicle*, double>& neighFollow,
158 const std::vector<MSVehicle::LaneQ>& preb,
162 #ifdef DEBUG_WANTS_CHANGE 164 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 171 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
176 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
178 #ifdef DEBUG_WANTS_CHANGE 191 #ifdef DEBUG_PATCH_SPEED 193 std::cout <<
"\nPATCH_SPEED\n" 200 <<
" wanted=" << wanted
207 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
209 #ifdef DEBUG_PATCH_SPEED 211 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
224 #ifdef DEBUG_PATCH_SPEED 231 <<
" wanted=" << wanted << std::endl;
236 double MAGIC_offset = 1.;
240 #ifdef DEBUG_PATCH_SPEED 251 #ifdef DEBUG_PATCH_SPEED 253 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
256 return MAX2(min, safe);
261 double nVSafe = wanted;
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);
1223 double roundaboutDistanceAhead = 0;
1224 double roundaboutDistanceAheadNeigh = 0;
1225 int roundaboutEdgesAhead = 0;
1226 int roundaboutEdgesAheadNeigh = 0;
1228 getRoundaboutAheadInfo(
this, curr, neigh, roundaboutDistanceAhead, roundaboutDistanceAheadNeigh, roundaboutEdgesAhead, roundaboutEdgesAheadNeigh);
1232 neighDist +=
roundaboutDistBonus(roundaboutDistanceAheadNeigh, roundaboutEdgesAheadNeigh);
1234 #ifdef DEBUG_WANTS_CHANGE 1236 if (roundaboutEdgesAhead > 0) {
1237 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1245 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1246 const double neighLeftPlace =
MAX2((
double) 0, neighDist - posOnLane - maxJam);
1249 double thisLaneVSafe = vMax;
1254 #ifdef DEBUG_WANTS_CHANGE 1259 <<
" laDist=" << laDist
1260 <<
" currentDist=" << currentDist
1261 <<
" usableDist=" << usableDist
1262 <<
" bestLaneOffset=" << bestLaneOffset
1264 <<
" best.length=" << best.
length 1265 <<
" maxJam=" << maxJam
1266 <<
" neighDist=" << neighDist
1267 <<
" neighLeftPlace=" << neighLeftPlace
1272 bool changeLeftToAvoidOvertakeRight =
false;
1279 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1286 double vSafe =
MAX2(
1293 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1296 const double deltaGapFuture = deltaV * 8;
1299 if (vSafeFuture < vSafe) {
1300 const double relativeGain = deltaV /
MAX2(vMax,
1303 changeLeftToAvoidOvertakeRight =
true;
1305 #ifdef DEBUG_WANTS_CHANGE 1308 <<
" avoid overtaking on the right nv=" << nv->
getID()
1309 <<
" deltaV=" << deltaV
1318 const double overtakeDist = (leader.first == 0 ? -1 :
1322 &&
MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1324 && (!checkOverTakeRight || !right)
1325 && (neighLead.first == 0 || !neighLead.first->isStopped()
1327 || neighLead.second > overtakeDist)) {
1330 #ifdef DEBUG_WANTS_CHANGE 1332 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" overtake stopped leader=" << leader.first->getID()
1333 <<
" overtakeDist=" << overtakeDist
1334 <<
" remaining=" <<
MIN2(neighDist, currentDist) - posOnLane
1339 }
else if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1346 #ifdef DEBUG_WANTS_CHANGE 1348 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1352 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1357 #ifdef DEBUG_WANTS_CHANGE 1359 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1363 }
else if (bestLaneOffset == 0
1364 && (leader.first == 0 || !leader.first->isStopped())
1366 && roundaboutEdgesAhead == 0
1372 #ifdef DEBUG_WANTS_CHANGE 1374 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1381 #ifdef DEBUG_WANTS_CHANGE 1389 if ((ret & lcaCounter) != 0) {
1393 #ifdef DEBUG_WANTS_CHANGE 1395 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
1406 if (changeToBest && abs(bestLaneOffset) > 1) {
1409 #ifdef DEBUG_WANTS_CHANGE 1411 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1419 if (*firstBlocked != neighLead.first) {
1423 const int remainingLanes =
MAX2(1, abs(bestLaneOffset));
1425 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1429 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1434 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1437 #ifdef DEBUG_WANTS_CHANGE 1442 <<
" remainingSeconds=" << remainingSeconds
1443 <<
" plannedSpeed=" << plannedSpeed
1451 const double inconvenience =
MIN2((
double)1.0, (laneOffset < 0
1458 if (roundaboutEdgesAhead > 1) {
1460 #ifdef DEBUG_WANTS_CHANGE 1464 <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead
1494 #ifdef DEBUG_WANTS_CHANGE 1496 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1516 && (!speedGainInconvenient)
1518 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1521 #ifdef DEBUG_COOPERATE 1525 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1527 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1556 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1557 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1559 if (acceleratingLeader) {
1566 if (neighLead.first == 0) {
1570 &
myVehicle, correctedSpeed, neighLead.second, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1572 if (leader.first == 0) {
1576 &
myVehicle, correctedSpeed, leader.second, leader.first->
getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1579 if (neighLead.first == 0) {
1583 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel(),
true));
1585 if (leader.first == 0) {
1589 leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel(),
true));
1599 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1602 #ifdef DEBUG_WANTS_CHANGE 1606 <<
" currentDist=" << currentDist
1607 <<
" neighDist=" << neighDist
1608 <<
" thisVSafe=" << thisLaneVSafe
1609 <<
" neighVSafe=" << neighLaneVSafe
1610 <<
" relGain=" <<
toString(relativeGain, 8)
1617 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1634 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1643 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1644 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1645 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1647 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1648 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1651 if (checkOverTakeRight && leader.first != 0
1652 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1653 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1654 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1655 const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1664 #ifdef DEBUG_WANTS_CHANGE 1669 <<
" neighDist=" << neighDist
1671 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1673 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1674 <<
" acceptanceTime=" << acceptanceTime
1675 <<
" fullSpeedGap=" << fullSpeedGap
1676 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1677 <<
" dProb=" << deltaProb
1690 #ifdef DEBUG_WANTS_CHANGE 1696 <<
" thisLaneVSafe=" << thisLaneVSafe
1697 <<
" neighLaneVSafe=" << neighLaneVSafe
1698 <<
" relativeGain=" << relativeGain
1699 <<
" blocked=" << blocked
1713 if (thisLaneVSafe > neighLaneVSafe) {
1718 }
else if (thisLaneVSafe == neighLaneVSafe) {
1736 #ifdef DEBUG_WANTS_CHANGE 1742 <<
" thisLaneVSafe=" << thisLaneVSafe
1743 <<
" neighLaneVSafe=" << neighLaneVSafe
1744 <<
" relativeGain=" << relativeGain
1745 <<
" blocked=" << blocked
1751 && (relativeGain >
NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1761 && relativeGain >= 0
1762 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1769 #ifdef DEBUG_WANTS_CHANGE 1775 <<
" thisLaneVSafe=" << thisLaneVSafe
1776 <<
" neighLaneVSafe=" << neighLaneVSafe
1787 double& roundaboutDistanceAhead,
double& roundaboutDistanceAheadNeigh,
int& roundaboutEdgesAhead,
int& roundaboutEdgesAheadNeigh) {
1799 roundaboutDistanceAheadNeigh = 0;
1800 double neighPosition = pos;
1808 MSLane* nextLane =
nullptr;
1810 if (*i !=
nullptr && *i != veh.
getLane()) {
1815 assert(nextLane != 0);
1824 #ifdef DEBUG_WANTS_CHANGE 1826 std::cout <<
"roundaboutDistanceAhead = " << roundaboutDistanceAhead
1827 <<
" roundaboutDistanceAheadNeigh = " << roundaboutDistanceAheadNeigh
1834 roundaboutEdgesAhead = 0;
1836 const MSLane* lane = *it;
1838 roundaboutEdgesAhead += 1;
1839 }
else if (roundaboutEdgesAhead > 0) {
1844 roundaboutEdgesAheadNeigh = 0;
1846 if ((*it) !=
nullptr && (*it)->getEdge().isRoundabout()) {
1847 roundaboutEdgesAheadNeigh += 1;
1848 }
else if (roundaboutEdgesAheadNeigh > 0) {
1865 if (roundaboutEdgesAhead > 1) {
1888 for (std::vector<MSLane*>::const_iterator i = continuationLanes.begin(); i != continuationLanes.end(); i++) {
1889 assert((*i) == 0 || !(*i)->getEdge().isInternal());
1893 bool encounteredRoundabout =
false;
1894 double roundaboutDistanceAhead = 0.;
1897 std::vector<MSLane*>::const_iterator j = continuationLanes.begin();
1898 while (j != continuationLanes.end() && *j ==
nullptr) {
1903 if (j == continuationLanes.end()) {
1905 assert(initialLane == 0);
1907 }
else if (initialLane ==
nullptr) {
1912 }
else if (!initialLane->
isInternal() && initialLane != *j) {
1919 assert(position >= 0. && position <= initialLane->getLength());
1921 assert(initialLane == *j);
1922 roundaboutDistanceAhead += initialLane->
getLength() - position;
1923 if (j + 1 == continuationLanes.end() || *(j + 1) ==
nullptr || !(*(j + 1))->getEdge().isRoundabout()) {
1927 const MSLane* nextLane = *(j + 1);
1935 roundaboutDistanceAhead += initialLane->
getLength() - position;
1937 roundaboutDistanceAhead += initialLane->
getLinkCont()[0]->getInternalLengthsAfter();
1942 for (std::vector<MSLane*>::const_iterator it = j; it != continuationLanes.end(); ++it) {
1943 const MSLane* lane = *it;
1946 encounteredRoundabout =
true;
1948 roundaboutDistanceAhead += lane->
getLength();
1953 if (it + 1 != continuationLanes.end() && *(it + 1) !=
nullptr && (*(it + 1))->getEdge().isRoundabout()) {
1958 roundaboutDistanceAhead += linkLength;
1960 }
else if (encounteredRoundabout) {
1965 return roundaboutDistanceAhead;
1973 if ((*blocked) !=
nullptr) {
1975 #ifdef DEBUG_SLOW_DOWN 1999 (*blocked)->getCarFollowModel().getMaxDecel()));
2002 #ifdef DEBUG_SLOW_DOWN 2006 <<
" slowing down for" 2028 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2044 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2056 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2062 <<
" potential=" << potential
2075 #ifdef DEBUG_WANTS_CHANGE 2077 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
2083 if (leader.first != 0) {
2085 v =
MIN2(v, stopSpeed);
2086 #ifdef DEBUG_WANTS_CHANGE 2088 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
2109 return MAX2(-speedBound,
MIN2(speedBound,
2125 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 getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
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 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...
int gPrecision
the precision for floating point outputs
double myKeepRightProbability
#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.
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 getInternalLengthsAfter() const
Returns the cumulative length of all internal lanes after this link.
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.
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()
static double distanceAlongNextRoundabout(double position, const MSLane *initialLane, const std::vector< MSLane *> &continuationLanes)
compute the distance on the next upcoming roundabout along a given sequence of lanes.
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
#define ROUNDABOUT_DIST_BONUS
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.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013...
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...
#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.
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.
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.
static void getRoundaboutAheadInfo(const MSLCM_LC2013 *lcm, const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, double &roundaboutDistanceAhead, double &roundaboutDistanceAheadNeigh, int &roundaboutEdgesAhead, int &roundaboutEdgesAheadNeigh)
computes the distance and number of edges in the next upcoming roundabout along the lane continuation...
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 ...
static MSLink * getConnectingLink(const MSLane &from, const MSLane &to)
Returns the link connecting both lanes Both lanes have to be non-internal; 0 may be returned if no co...
std::vector< MSLane * > bestContinuations
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()
#define ROUNDABOUT_DIST_TRESH
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
std::map< int, int > myCanceledStates
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.
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 roundaboutDistBonus(double roundaboutDistAhead, int roundaboutEdgesAhead) const
Computes the artificial bonus distance for roundabout lanes this additional distance reduces the sens...
double getOppositeSafetyFactor() const
return factor for modifying the safety constraints for opposite-diretction overtaking of the car-foll...