473 const std::pair<MSVehicle*, double>& neighLead,
474 double remainingSeconds) {
475 double plannedSpeed =
myVehicle.getSpeed();
477 plannedSpeed =
MIN2(plannedSpeed,
481 const double a = i.first;
482 if (a >= -
myVehicle.getCarFollowModel().getMaxDecel()) {
488 std::cout <<
"\nINFORM_LEADER"
489 <<
"\nspeed=" <<
myVehicle.getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
493 const MSVehicle*
const nv = neighLead.first;
501 neighNextGap = neighLead.second +
SPEED2DIST(neighNextSpeed - plannedSpeed);
512 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
519 const double dv = plannedSpeed - nv->
getSpeed();
522 overtakeTime = overtakeDist / dv;
527 overtakeTime = remainingSeconds - 1;
530 overtakeTime = remainingSeconds + 1;
536 <<
"\nnv = " << nv->
getID()
537 <<
"\nplannedSpeed = " << plannedSpeed
538 <<
"\nleaderSpeed = " << nv->
getSpeed()
540 <<
"\nremainingSeconds = " << remainingSeconds
541 <<
"\novertakeDist = " << overtakeDist
542 <<
"\novertakeTime = " << overtakeTime
557 && (!neighLead.first->isStopped() || (
isOpposite() && neighLead.second >= 0))) {
566 if (targetSpeed <
myVehicle.getSpeed()) {
568 const double decel = remainingSeconds == 0. ?
myVehicle.getCarFollowModel().getMaxDecel() :
575 <<
" cannot overtake leader nv=" << nv->
getID()
579 <<
" overtakeDist=" << overtakeDist
580 <<
" overtakeTime=" << overtakeTime
581 <<
" remainingSeconds=" << remainingSeconds
582 <<
" currentGap=" << neighLead.second
584 <<
" neighNextSpeed=" << neighNextSpeed
585 <<
" neighNextGap=" << neighNextGap
586 <<
" targetSpeed=" << targetSpeed
587 <<
" nextSpeed=" << nextSpeed
598 <<
" cannot overtake fast leader nv=" << nv->
getID()
602 <<
" overtakeDist=" << overtakeDist
604 <<
" overtakeTime=" << overtakeTime
605 <<
" remainingSeconds=" << remainingSeconds
606 <<
" currentGap=" << neighLead.second
607 <<
" neighNextSpeed=" << neighNextSpeed
608 <<
" neighNextGap=" << neighNextGap
609 <<
" targetSpeed=" << targetSpeed
621 <<
" wants to overtake leader nv=" << nv->
getID()
623 <<
" overtakeDist=" << overtakeDist
624 <<
" remainingSeconds=" << remainingSeconds
625 <<
" overtakeTime=" << overtakeTime
626 <<
" currentGap=" << neighLead.second
639 const double targetSpeed =
MAX2(
645 std::cout <<
" not blocked by leader nv=" << nv->
getID()
647 <<
" gap=" << neighLead.second
648 <<
" neighNextSpeed=" << neighNextSpeed
649 <<
" neighNextGap=" << neighNextGap
651 <<
" targetSpeed=" << targetSpeed
655 return MIN2(targetSpeed, plannedSpeed);
663 const std::pair<MSVehicle*, double>& neighFollow,
664 double remainingSeconds,
665 double plannedSpeed) {
672 std::cout <<
"\nINFORM_FOLLOWER"
673 <<
"\nspeed=" <<
myVehicle.getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
684 std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
692 if ((neededGap - neighFollow.second) / remainingSeconds < (
MAX2(plannedSpeed, 0.) - nv->
getSpeed())) {
695 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help." <<
"\nneededGap = " << neededGap <<
"\n";
715 double neighNewSpeed;
717 double neighNewSpeed1s;
727 dv = plannedSpeed - neighNewSpeed1s;
734 decelGap = neighFollow.second + dv;
741 neighNewSpeed1s = nv->
getSpeed() - helpDecel;
749 MAX2(plannedSpeed, 0.),
myVehicle.getCarFollowModel().getMaxDecel());
757 <<
" plannedSpeed=" << plannedSpeed
758 <<
" threshold=" << onRampThreshold
759 <<
" neighNewSpeed=" << neighNewSpeed
760 <<
" neighNewSpeed1s=" << neighNewSpeed1s
762 <<
" gap=" << neighFollow.second
763 <<
" decelGap=" << decelGap
764 <<
" secureGap=" << secureGap
771 && neighNewSpeed1s < onRampThreshold) {
775 if (decelGap > 0 && decelGap >= secureGap) {
783 double vsafe, vsafe1;
800 neighFollow.second,
myVehicle.getSpeed(),
805 std::cout <<
"nextGap=" << nextGap <<
" (without help decel) \n";
813 MAX2(0., plannedSpeed),
820 neighFollow.second,
myVehicle.getSpeed(),
821 nv->
getSpeed(), plannedAccel, -decel2,
831 MAX2(0., plannedSpeed),
834 assert(vsafe >= vsafe1 - NUMERICAL_EPS);
838 std::cout <<
"nextGap=" << nextGap
839 <<
" (with vsafe1 and help decel) \nvsafe1=" << vsafe1
840 <<
" vsafe=" << vsafe
849 if (nextGap < nextSecureGap) {
851 vsafe = neighNewSpeed;
856 std::cout <<
"nextGap=" << nextGap
857 <<
" minNextSecureGap=" << nextSecureGap
858 <<
" vsafe=" << vsafe <<
"\n";
868 std::cout <<
" wants to cut in before nv=" << nv->
getID()
869 <<
" vsafe1=" << vsafe1 <<
" vsafe=" << vsafe
873 myVehicle.getCarFollowModel().getMaxDecel())
897 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
906 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
929 std::cout <<
" wants right follower to slow down a bit\n";
939 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
961 if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) {
964 std::cout <<
" wants to cut in before follower nv=" << nv->
getID() <<
" (eventually)\n";
981 <<
" informs follower " << nv->
getID()
982 <<
" vhelp=" << vhelp
991 const double needDV = overtakeDist / remainingSeconds;
999 <<
" wants to be overtaken by=" << nv->
getID()
1000 <<
" overtakeDist=" << overtakeDist
1002 <<
" vhelp=" << vhelp
1003 <<
" needDV=" << needDV
1014#ifdef DEBUG_INFORMER
1016 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
1101 const std::pair<MSVehicle*, double>& leader,
1102 const std::pair<MSVehicle*, double>& follower,
1103 const std::pair<MSVehicle*, double>& neighLead,
1104 const std::pair<MSVehicle*, double>& neighFollow,
1106 const std::vector<MSVehicle::LaneQ>& preb,
1109 assert(laneOffset == 1 || laneOffset == -1);
1113 int bestLaneOffset = 0;
1118 double currentDist = 0;
1119 double neighDist = 0;
1121 const bool checkOpposite = &neighLane.
getEdge() != &
myVehicle.getLane()->getEdge();
1132 const int prebOffset = laneOffset;
1133 for (
int p = 0; p < (int) preb.size(); ++p) {
1137 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1138 assert(p + prebOffset < (
int)preb.size());
1140 neigh = preb[p + prebOffset];
1141 currentDist = curr.
length;
1142 neighDist = neigh.
length;
1144 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0 && !checkOpposite) {
1145#ifdef DEBUG_WANTS_CHANGE
1149 <<
" bestLaneOffsetOld=" << bestLaneOffset
1150 <<
" bestLaneOffsetNew=" << laneOffset
1154 bestLaneOffset = prebOffset;
1156 best = preb[p + bestLaneOffset];
1161 assert(curr.
lane !=
nullptr);
1162 assert(neigh.
lane !=
nullptr);
1163 assert(best.
lane !=
nullptr);
1165 const bool right = (laneOffset == -1);
1167 double driveToNextStop = -std::numeric_limits<double>::max();
1168 if (
myVehicle.nextStopDist() < std::numeric_limits<double>::max()
1173 driveToNextStop =
myVehicle.nextStopDist();
1174 const double stopPos = posOnLane +
myVehicle.nextStopDist() -
myVehicle.getLastStepDist();
1175#ifdef DEBUG_WANTS_CHANGE
1178 <<
" stopDist=" <<
myVehicle.nextStopDist()
1179 <<
" lastDist=" <<
myVehicle.getLastStepDist()
1180 <<
" stopPos=" << stopPos
1181 <<
" currentDist=" << currentDist
1182 <<
" neighDist=" << neighDist
1186 currentDist =
MAX2(currentDist, stopPos);
1187 neighDist =
MAX2(neighDist, stopPos);
1192 bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1198 if (lastBlocked != firstBlocked) {
1202#ifdef DEBUG_WANTS_CHANGE
1211 <<
" leaderGap=" << leader.second
1213 <<
" followerGap=" << follower.second
1215 <<
" neighLeadGap=" << neighLead.second
1217 <<
" neighFollowGap=" << neighFollow.second
1240 assert(memoryFactor > 0.);
1245 laDist +=
myVehicle.getVehicleType().getLengthWithGap() * 2.;
1246 const bool hasStoppedLeader = leader.first != 0 && leader.first->isStopped() && leader.second < (currentDist - posOnLane);
1250 if (bestLaneOffset == 0 && hasBidiLeader) {
1253 }
else if (bestLaneOffset == 0 && hasStoppedLeader) {
1257 laDist = 0.5 * (
myVehicle.getVehicleType().getLengthWithGap()
1258 + leader.first->getVehicleType().getLengthWithGap()
1260 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && (neighLead.first->isStopped() || hasBidiNeighLeader) && neighLead.second < (currentDist - posOnLane)) {
1264 laDist = (
myVehicle.getVehicleType().getLengthWithGap()
1265 + neighLead.first->getVehicleType().getLengthWithGap()
1266 + neighLead.second);
1267 }
else if (!hasStoppedLeader &&
1268 ((neighLead.second +
myVehicle.getVehicleType().getLengthWithGap() + neighLead.first->getVehicleType().getLengthWithGap()) < (currentDist - posOnLane)
1269 || hasBidiNeighLeader)) {
1272 changeToBest =
false;
1291 currentDist += roundaboutBonus;
1292 neighDist += roundaboutBonus;
1296 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1300 double thisLaneVSafe = vMax;
1303 double neighLeftPlace =
MAX2(0.0, neighDist - posOnLane - maxJam);
1304 if (neighLead.first != 0 && neighLead.first->isStopped()) {
1305 neighLeftPlace =
MIN2(neighLeftPlace, neighLead.second);
1308#ifdef DEBUG_WANTS_CHANGE
1313 <<
" laDist=" << laDist
1314 <<
" currentDist=" << currentDist
1315 <<
" usableDist=" << usableDist
1316 <<
" bestLaneOffset=" << bestLaneOffset
1318 <<
" best.length=" << best.
length
1319 <<
"\n roundaboutBonus=" << roundaboutBonus
1320 <<
" maxJam=" << maxJam
1321 <<
" neighDist=" << neighDist
1322 <<
" neighLeftPlace=" << neighLeftPlace
1323 << (hasBidiLeader ?
" bidiLeader" :
"")
1324 << (hasBidiNeighLeader ?
" bidiNeighLeader" :
"")
1329 bool changeLeftToAvoidOvertakeRight =
false;
1336 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1346 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1349 const double deltaGapFuture = deltaV * 8;
1352 if (vSafeFuture < vSafe) {
1353 const double relativeGain = deltaV /
MAX2(vMax,
1356 changeLeftToAvoidOvertakeRight =
true;
1358#ifdef DEBUG_WANTS_CHANGE
1361 <<
" avoid overtaking on the right nv=" << nv->
getID()
1362 <<
" deltaV=" << deltaV
1372 const bool currFreeUntilNeighEnd = leader.first ==
nullptr || neighDist - posOnLane <= leader.second;
1373 const double overtakeDist = (leader.first == 0 || hasBidiLeader ? -1 :
1374 leader.second +
myVehicle.getVehicleType().getLength() + leader.first->getVehicleType().getLengthWithGap());
1375 const double overtakeDist2 = (neighLead.first == 0 || !neighLead.first->isStopped() ? -1 :
1376 neighLead.second +
myVehicle.getVehicleType().getLength() + neighLead.first->getVehicleType().getLengthWithGap());
1379 &&
MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1381 && (!checkOverTakeRight || !right)
1383 && (neighLead.first == 0 || !neighLead.first->isStopped()
1385 || neighLead.second > overtakeDist
1387 || (overtakeDist2 > leader.second &&
hasFreeLane(laneOffset, neighLead)))) {
1389 currentDist =
myVehicle.getPositionOnLane() + leader.second;
1390#ifdef DEBUG_WANTS_CHANGE
1392 std::cout <<
" veh=" <<
myVehicle.getID() <<
" overtake stopped leader=" << leader.first->getID()
1393 <<
" overtakeDist=" << overtakeDist
1394 <<
" overtakeDist2=" << overtakeDist
1395 <<
" hasFreeLane=" <<
hasFreeLane(laneOffset, neighLead)
1396 <<
" remaining=" <<
MIN2(neighDist, currentDist) - posOnLane
1401 }
else if (!changeToBest &&
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist) && !hasBidiLeader) {
1408#ifdef DEBUG_WANTS_CHANGE
1410 std::cout <<
" veh=" <<
myVehicle.getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1414 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1419#ifdef DEBUG_WANTS_CHANGE
1421 std::cout <<
" veh=" <<
myVehicle.getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1425 }
else if (bestLaneOffset == 0
1426 && (leader.first == 0 || !leader.first->isStopped())
1429 && roundaboutBonus == 0
1438#ifdef DEBUG_WANTS_CHANGE
1440 std::cout <<
" veh=" <<
myVehicle.getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1447#ifdef DEBUG_WANTS_CHANGE
1454 ret =
myVehicle.influenceChangeDecision(ret);
1455 if ((ret & lcaCounter) != 0) {
1459#ifdef DEBUG_WANTS_CHANGE
1474 if (changeToBest && abs(bestLaneOffset) > 1 &&
myVehicle.getNumRemainingEdges() > 1) {
1477#ifdef DEBUG_SAVE_BLOCKER_LENGTH
1479 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1488 if (firstBlocked != neighLead.first) {
1491#ifdef DEBUG_SAVE_BLOCKER_LENGTH
1493 std::cout <<
SIMTIME <<
" canReserve=" << canReserve <<
" canContinue=" << canContinue <<
"\n";
1502 const int remainingLanes =
MAX2(1, abs(bestLaneOffset));
1504 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1507 myVehicle.getInfluencer().changeRequestRemainingSeconds(currentTime));
1508 if (!hasBidiNeighLeader) {
1509 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1515 if (!hasBidiNeighFollower) {
1516 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1519#ifdef DEBUG_WANTS_CHANGE
1524 <<
" remainingSeconds=" << remainingSeconds
1525 <<
" plannedSpeed=" << plannedSpeed
1530#ifdef DEBUG_WANTS_CHANGE
1535 <<
" remainingSeconds=" << remainingSeconds
1536 <<
" hasBidiNeighLeader\n";
1549 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1550 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1561 double inconvenience = laneOffset < 0
1565 const double relSpeedDiff = thisLaneVSafe == 0 ? 0 : (thisLaneVSafe - neighLaneVSafe) /
MAX2(thisLaneVSafe, neighLaneVSafe);
1566 inconvenience =
MAX2(relSpeedDiff, inconvenience);
1567 inconvenience =
MIN2(1.0, inconvenience);
1571#ifdef DEBUG_WANTS_CHANGE
1577 <<
" neighSpeedFactor=" << (thisLaneVSafe / neighLaneVSafe - 1)
1578 <<
" inconvenience=" << inconvenience
1579 <<
" speedInconv=" << speedGainInconvenient
1580 <<
" occInconv=" << neighOccupancyInconvenient
1586 if (roundaboutBonus > 0) {
1588#ifdef DEBUG_WANTS_CHANGE
1592 <<
" roundaboutBonus=" << roundaboutBonus
1622#ifdef DEBUG_WANTS_CHANGE
1624 std::cout <<
" veh=" <<
myVehicle.getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1644 && (!speedGainInconvenient)
1646 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1649#ifdef DEBUG_COOPERATE
1653 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1655 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1664 if (nv !=
nullptr && !hasBidiNeighFollower) {
1694 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1697#ifdef DEBUG_WANTS_CHANGE
1701 <<
" currentDist=" << currentDist
1702 <<
" neighDist=" << neighDist
1703 <<
" thisVSafe=" << thisLaneVSafe
1704 <<
" neighVSafe=" << neighLaneVSafe
1705 <<
" relGain=" <<
toString(relativeGain, 8)
1712 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1721 const double roadSpeedFactor = vMax /
myVehicle.getLane()->getSpeedLimit();
1722 double acceptanceTime;
1726 acceptanceTime = 7 * roadSpeedFactor *
MAX2(1.0,
myVehicle.getSpeed());
1729 if (follower.first !=
nullptr && follower.second < 2 * follower.first->getCarFollowModel().brakeGap(follower.first->getSpeed())) {
1731 if (follower.first->getSpeed() >=
myVehicle.getSpeed()) {
1732 acceptanceTime *=
MAX2(1.0,
myVehicle.getSpeed()) /
MAX2(1.0, follower.first->getSpeed());
1733 const double fRSF = follower.first->getLane()->getVehicleMaxSpeed(follower.first) / follower.first->getLane()->getSpeedLimit();
1734 if (fRSF > roadSpeedFactor) {
1735 acceptanceTime /= fRSF;
1740 double fullSpeedGap =
MAX2(0., neighDist -
myVehicle.getCarFollowModel().brakeGap(vMax));
1741 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1742 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1743 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1744 neighLead.second -
myVehicle.getCarFollowModel().getSecureGap(&
myVehicle, neighLead.first,
1745 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1746 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1749 if (checkOverTakeRight && leader.first != 0
1750 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1751 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1752 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1767#ifdef DEBUG_WANTS_CHANGE
1772 <<
" neighDist=" << neighDist
1774 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1775 <<
" secGap=" << (neighLead.first == 0 ? -1 :
myVehicle.getCarFollowModel().getSecureGap(&
myVehicle, neighLead.first,
1776 myVehicle.getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1777 <<
" acceptanceTime=" << acceptanceTime
1778 <<
" fullSpeedGap=" << fullSpeedGap
1779 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1793#ifdef DEBUG_WANTS_CHANGE
1800 <<
" thisLaneVSafe=" << thisLaneVSafe
1801 <<
" neighLaneVSafe=" << neighLaneVSafe
1802 <<
" relativeGain=" << relativeGain
1803 <<
" blocked=" << blocked
1820 if (thisLaneVSafe > neighLaneVSafe) {
1823 }
else if (thisLaneVSafe == neighLaneVSafe) {
1838#ifdef DEBUG_WANTS_CHANGE
1845 <<
" thisLaneVSafe=" << thisLaneVSafe
1846 <<
" neighLaneVSafe=" << neighLaneVSafe
1847 <<
" relativeGain=" << relativeGain
1848 <<
" blocked=" << blocked
1854 && (relativeGain > NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1864 if (nv !=
nullptr && !hasBidiNeighFollower) {
1876 && relativeGain >= 0
1884#ifdef DEBUG_WANTS_CHANGE
1891 <<
" thisLaneVSafe=" << thisLaneVSafe
1892 <<
" neighLaneVSafe=" << neighLaneVSafe