47 #define LOOK_FORWARD 10.
51 #define LCA_RIGHT_IMPATIENCE -1.
52 #define CUT_IN_LEFT_SPEED_THRESHOLD 27.
54 #define LOOK_AHEAD_MIN_SPEED 0.0
55 #define LOOK_AHEAD_SPEED_MEMORY 0.9
57 #define HELP_DECEL_FACTOR 1.0
59 #define HELP_OVERTAKE (10.0 / 3.6)
60 #define MIN_FALLBEHIND (7.0 / 3.6)
62 #define RELGAIN_NORMALIZATION_MIN_SPEED 10.0
64 #define OPPOSITE_URGENCY 5.0
66 #define KEEP_RIGHT_TIME 5.0
68 #define KEEP_RIGHT_HEADWAY 2.0
69 #define MAX_ONRAMP_LENGTH 200.
70 #define TURN_LANE_DIST 200.0
72 #define LC_RESOLUTION_SPEED_LAT 0.5
73 #define LC_ASSUMED_DECEL 1.0
75 #define REACT_TO_STOPPED_DISTANCE 100
90 #define DEBUG_COND (myVehicle.isSelected())
98 mySpeedGainProbability(0),
99 myKeepRightProbability(0),
100 myLeadingBlockerLength(0),
118 #ifdef DEBUG_CONSTRUCTOR
154 const std::pair<MSVehicle*, double>& leader,
155 const std::pair<MSVehicle*, double>& follower,
156 const std::pair<MSVehicle*, double>& neighLead,
157 const std::pair<MSVehicle*, double>& neighFollow,
159 const std::vector<MSVehicle::LaneQ>& preb,
163 #ifdef DEBUG_WANTS_CHANGE
165 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME
172 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
177 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, follower, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
179 #ifdef DEBUG_WANTS_CHANGE
192 #ifdef DEBUG_PATCH_SPEED
194 std::cout <<
"\nPATCH_SPEED\n"
201 <<
" wanted=" << wanted
208 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
210 #ifdef DEBUG_PATCH_SPEED
212 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
225 #ifdef DEBUG_PATCH_SPEED
232 <<
" wanted=" << wanted << std::endl;
237 double MAGIC_offset = 1.;
238 double nVSafe = wanted;
243 #ifdef DEBUG_PATCH_SPEED
254 #ifdef DEBUG_PATCH_SPEED
256 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe + NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
259 nVSafe =
MAX2(min, safe);
277 nVSafe =
MIN2(v * coopWeight + (1 - coopWeight) * wanted, nVSafe);
279 #ifdef DEBUG_PATCH_SPEED
286 #ifdef DEBUG_PATCH_SPEED
288 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
292 #ifdef DEBUG_PATCH_SPEED
294 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
302 #ifdef DEBUG_PATCH_SPEED
315 #ifdef DEBUG_PATCH_SPEED
320 return (max + wanted) / 2.0;
324 #ifdef DEBUG_PATCH_SPEED
330 return (
MAX2(0., min) + wanted) / 2.0;
336 #ifdef DEBUG_PATCH_SPEED
341 return (max + wanted) / 2.0;
382 #ifdef DEBUG_PATCH_SPEED
387 return (max + wanted) / 2.0;
391 #ifdef DEBUG_PATCH_SPEED
419 #ifdef DEBUG_INFORMED
423 <<
" informedBy=" << sender->
getID()
424 <<
" info=" << pinfo->second
425 <<
" vSafe=" << pinfo->first
437 double overtakeDist = (gap
442 return MAX2(overtakeDist, 0.);
450 const std::pair<MSVehicle*, double>& neighLead,
451 double remainingSeconds) {
460 #ifdef DEBUG_INFORMER
462 std::cout <<
"\nINFORM_LEADER"
467 const MSVehicle*
const nv = neighLead.first;
475 neighNextGap = neighLead.second +
SPEED2DIST(neighNextSpeed - plannedSpeed);
480 #ifdef DEBUG_INFORMER
482 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
489 const double dv = plannedSpeed - nv->
getSpeed();
492 overtakeTime = overtakeDist / dv;
495 overtakeTime = remainingSeconds + 1;
498 #ifdef DEBUG_INFORMER
501 <<
"\nnv = " << nv->
getID()
502 <<
"\nplannedSpeed = " << plannedSpeed
503 <<
"\nleaderSpeed = " << nv->
getSpeed()
505 <<
"\nremainingSeconds = " << remainingSeconds
506 <<
"\novertakeDist = " << overtakeDist
507 <<
"\novertakeTime = " << overtakeTime
522 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
527 const double targetSpeed =
MAX2(
536 #ifdef DEBUG_INFORMER
539 <<
" cannot overtake leader nv=" << nv->
getID()
543 <<
" overtakeDist=" << overtakeDist
544 <<
" overtakeTime=" << overtakeTime
545 <<
" remainingSeconds=" << remainingSeconds
546 <<
" currentGap=" << neighLead.second
548 <<
" neighNextSpeed=" << neighNextSpeed
549 <<
" neighNextGap=" << neighNextGap
550 <<
" targetSpeed=" << targetSpeed
551 <<
" nextSpeed=" << nextSpeed
559 #ifdef DEBUG_INFORMER
562 <<
" cannot overtake fast leader nv=" << nv->
getID()
566 <<
" overtakeDist=" << overtakeDist
568 <<
" overtakeTime=" << overtakeTime
569 <<
" remainingSeconds=" << remainingSeconds
570 <<
" currentGap=" << neighLead.second
571 <<
" targetSpeed=" << targetSpeed
580 #ifdef DEBUG_INFORMER
583 <<
" wants to overtake leader nv=" << nv->
getID()
585 <<
" overtakeDist=" << overtakeDist
586 <<
" remainingSeconds=" << remainingSeconds
587 <<
" overtakeTime=" << overtakeTime
588 <<
" currentGap=" << neighLead.second
598 const double targetSpeed =
MAX2(
602 #ifdef DEBUG_INFORMER
604 std::cout <<
" not blocked by leader nv=" << nv->
getID()
606 <<
" gap=" << neighLead.second
607 <<
" neighNextSpeed=" << neighNextSpeed
608 <<
" neighNextGap=" << neighNextGap
610 <<
" targetSpeed=" << targetSpeed
614 return MIN2(targetSpeed, plannedSpeed);
622 const std::pair<MSVehicle*, double>& neighFollow,
623 double remainingSeconds,
624 double plannedSpeed) {
629 #ifdef DEBUG_INFORMER
631 std::cout <<
"\nINFORM_FOLLOWER"
637 #ifdef DEBUG_INFORMER
639 std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
647 if ((neededGap - neighFollow.second) / remainingSeconds < (
MAX2(plannedSpeed, 0.) - nv->
getSpeed())) {
648 #ifdef DEBUG_INFORMER
650 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help." <<
"\nneededGap = " << neededGap <<
"\n";
670 double neighNewSpeed;
672 double neighNewSpeed1s;
682 dv = plannedSpeed - neighNewSpeed1s;
689 decelGap = neighFollow.second + dv;
696 neighNewSpeed1s = nv->
getSpeed() - helpDecel;
708 #ifdef DEBUG_INFORMER
712 <<
" plannedSpeed=" << plannedSpeed
713 <<
" threshold=" << onRampThreshold
714 <<
" neighNewSpeed=" << neighNewSpeed
715 <<
" neighNewSpeed1s=" << neighNewSpeed1s
717 <<
" gap=" << neighFollow.second
718 <<
" decelGap=" << decelGap
719 <<
" secureGap=" << secureGap
726 && neighNewSpeed1s < onRampThreshold) {
730 if (decelGap > 0 && decelGap >= secureGap) {
738 double vsafe, vsafe1;
758 #ifdef DEBUG_INFORMER
760 std::cout <<
"nextGap=" << nextGap <<
" (without help decel) \n";
768 MAX2(0., plannedSpeed),
776 nv->
getSpeed(), plannedAccel, -decel2,
786 MAX2(0., plannedSpeed),
789 assert(vsafe >= vsafe1 - NUMERICAL_EPS);
791 #ifdef DEBUG_INFORMER
793 std::cout <<
"nextGap=" << nextGap
794 <<
" (with vsafe1 and help decel) \nvsafe1=" << vsafe1
795 <<
" vsafe=" << vsafe
804 if (nextGap < nextSecureGap) {
806 vsafe = neighNewSpeed;
809 #ifdef DEBUG_INFORMER
811 std::cout <<
"nextGap=" << nextGap
812 <<
" minNextSecureGap=" << nextSecureGap
813 <<
" vsafe=" << vsafe <<
"\n";
821 #ifdef DEBUG_INFORMER
823 std::cout <<
" wants to cut in before nv=" << nv->
getID()
824 <<
" vsafe1=" << vsafe1 <<
" vsafe=" << vsafe
850 #ifdef DEBUG_INFORMER
852 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
859 #ifdef DEBUG_INFORMER
861 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
880 #ifdef DEBUG_INFORMER
884 std::cout <<
" wants right follower to slow down a bit\n";
891 #ifdef DEBUG_INFORMER
894 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
916 if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) {
917 #ifdef DEBUG_INFORMER
919 std::cout <<
" wants to cut in before follower nv=" << nv->
getID() <<
" (eventually)\n";
932 #ifdef DEBUG_INFORMER
936 <<
" informs follower " << nv->
getID()
937 <<
" vhelp=" << vhelp
946 const double needDV = overtakeDist / remainingSeconds;
950 #ifdef DEBUG_INFORMER
954 <<
" wants to be overtaken by=" << nv->
getID()
955 <<
" overtakeDist=" << overtakeDist
957 <<
" vhelp=" << vhelp
958 <<
" needDV=" << needDV
967 double vsafe, vsafe1;
970 MSVehicle*
const nfv = neighFollow.first;
980 double anticipationTime = 1.;
991 if (anticipatedGap > secureGap) {
998 if (anticipatedGap < secureGap) {
1009 #ifdef DEBUG_INFORMER
1011 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
1040 scaledDelta =
MIN2(overlap, maxDist);
1049 deltaPosLat =
MAX2(
MIN2(deltaPosLat, maxDist), -maxDist);
1079 const std::pair<MSVehicle*, double>& leader,
1080 const std::pair<MSVehicle*, double>& follower,
1081 const std::pair<MSVehicle*, double>& neighLead,
1082 const std::pair<MSVehicle*, double>& neighFollow,
1084 const std::vector<MSVehicle::LaneQ>& preb,
1087 assert(laneOffset == 1 || laneOffset == -1);
1091 int bestLaneOffset = 0;
1096 double currentDist = 0;
1097 double neighDist = 0;
1110 const int prebOffset = laneOffset;
1111 for (
int p = 0; p < (int) preb.size(); ++p) {
1115 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1116 assert(p + prebOffset < (
int)preb.size());
1118 neigh = preb[p + prebOffset];
1119 currentDist = curr.
length;
1120 neighDist = neigh.
length;
1122 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0 && !checkOpposite) {
1123 #ifdef DEBUG_WANTS_CHANGE
1127 <<
" bestLaneOffsetOld=" << bestLaneOffset
1128 <<
" bestLaneOffsetNew=" << laneOffset
1132 bestLaneOffset = prebOffset;
1134 best = preb[p + bestLaneOffset];
1139 assert(curr.
lane !=
nullptr);
1140 assert(neigh.
lane !=
nullptr);
1141 assert(best.
lane !=
nullptr);
1143 const bool right = (laneOffset == -1);
1145 double driveToNextStop = -std::numeric_limits<double>::max();
1153 #ifdef DEBUG_WANTS_CHANGE
1158 <<
" stopPos=" << stopPos
1159 <<
" currentDist=" << currentDist
1160 <<
" neighDist=" << neighDist
1164 currentDist =
MAX2(currentDist, stopPos);
1165 neighDist =
MAX2(neighDist, stopPos);
1170 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1176 if (lastBlocked != firstBlocked) {
1180 #ifdef DEBUG_WANTS_CHANGE
1189 <<
" leaderGap=" << leader.second
1191 <<
" followerGap=" << follower.second
1193 <<
" neighLeadGap=" << neighLead.second
1195 <<
" neighFollowGap=" << neighFollow.second
1218 assert(memoryFactor > 0.);
1226 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped() && leader.second < (currentDist - posOnLane)) {
1231 + leader.first->getVehicleType().getLengthWithGap()
1233 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped() && neighLead.second < (currentDist - posOnLane)) {
1236 + neighLead.first->getVehicleType().getLengthWithGap()
1237 + neighLead.second);
1255 currentDist += roundaboutBonus;
1256 neighDist += roundaboutBonus;
1260 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1261 const double neighLeftPlace =
MAX2(0.0, neighDist - posOnLane - maxJam);
1264 double thisLaneVSafe = vMax;
1270 #ifdef DEBUG_WANTS_CHANGE
1275 <<
" laDist=" << laDist
1276 <<
" currentDist=" << currentDist
1277 <<
" usableDist=" << usableDist
1278 <<
" bestLaneOffset=" << bestLaneOffset
1280 <<
" best.length=" << best.
length
1281 <<
"\n roundaboutBonus=" << roundaboutBonus
1282 <<
" maxJam=" << maxJam
1283 <<
" neighDist=" << neighDist
1284 <<
" neighLeftPlace=" << neighLeftPlace
1289 bool changeLeftToAvoidOvertakeRight =
false;
1296 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1308 if (vSafeFollow >= vMaxDecel) {
1309 vSafe = vSafeFollow;
1311 vSafe =
MAX2(vMaxDecel, vStayBehind);
1316 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1319 const double deltaGapFuture = deltaV * 8;
1322 if (vSafeFuture < vSafe) {
1323 const double relativeGain = deltaV /
MAX2(vMax,
1326 changeLeftToAvoidOvertakeRight =
true;
1328 #ifdef DEBUG_WANTS_CHANGE
1331 <<
" avoid overtaking on the right nv=" << nv->
getID()
1332 <<
" deltaV=" << deltaV
1341 const double overtakeDist = (leader.first == 0 ? -1 :
1345 &&
MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1347 && (!checkOverTakeRight || !right)
1348 && (neighLead.first == 0 || !neighLead.first->isStopped()
1350 || neighLead.second > overtakeDist)) {
1353 #ifdef DEBUG_WANTS_CHANGE
1355 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" overtake stopped leader=" << leader.first->getID()
1356 <<
" overtakeDist=" << overtakeDist
1357 <<
" remaining=" <<
MIN2(neighDist, currentDist) - posOnLane
1362 }
else if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1369 #ifdef DEBUG_WANTS_CHANGE
1371 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1375 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1380 #ifdef DEBUG_WANTS_CHANGE
1382 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1386 }
else if (bestLaneOffset == 0
1387 && (leader.first == 0 || !leader.first->isStopped())
1389 && roundaboutBonus == 0
1395 #ifdef DEBUG_WANTS_CHANGE
1397 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1404 #ifdef DEBUG_WANTS_CHANGE
1412 if ((ret & lcaCounter) != 0) {
1416 #ifdef DEBUG_WANTS_CHANGE
1431 if (changeToBest && abs(bestLaneOffset) > 1) {
1434 #ifdef DEBUG_WANTS_CHANGE
1436 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1444 if (*firstBlocked != neighLead.first) {
1448 const int remainingLanes =
MAX2(1, abs(bestLaneOffset));
1450 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1454 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1459 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1462 #ifdef DEBUG_WANTS_CHANGE
1467 <<
" remainingSeconds=" << remainingSeconds
1468 <<
" plannedSpeed=" << plannedSpeed
1478 const double inconvenience =
MIN2(1.0, (laneOffset < 0
1485 if (roundaboutBonus > 0) {
1487 #ifdef DEBUG_WANTS_CHANGE
1491 <<
" roundaboutBonus=" << roundaboutBonus
1521 #ifdef DEBUG_WANTS_CHANGE
1523 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1543 && (!speedGainInconvenient)
1545 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1548 #ifdef DEBUG_COOPERATE
1552 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1554 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1581 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1582 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1594 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1597 #ifdef DEBUG_WANTS_CHANGE
1601 <<
" currentDist=" << currentDist
1602 <<
" neighDist=" << neighDist
1603 <<
" thisVSafe=" << thisLaneVSafe
1604 <<
" neighVSafe=" << neighLaneVSafe
1605 <<
" relGain=" <<
toString(relativeGain, 8)
1612 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1629 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1635 double acceptanceTime;
1642 if (follower.first !=
nullptr && follower.second < 2 * follower.first->getCarFollowModel().brakeGap(follower.first->getSpeed())) {
1646 const double fRSF = follower.first->getLane()->getVehicleMaxSpeed(follower.first) / follower.first->getLane()->getSpeedLimit();
1647 if (fRSF > roadSpeedFactor) {
1648 acceptanceTime /= fRSF;
1654 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1655 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1656 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1658 vMax, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1659 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1662 if (checkOverTakeRight && leader.first != 0
1663 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1664 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1665 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1666 const double relGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1683 #ifdef DEBUG_WANTS_CHANGE
1688 <<
" neighDist=" << neighDist
1690 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1692 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1693 <<
" acceptanceTime=" << acceptanceTime
1694 <<
" fullSpeedGap=" << fullSpeedGap
1695 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1696 <<
" dProb=" << deltaProb
1709 #ifdef DEBUG_WANTS_CHANGE
1715 <<
" thisLaneVSafe=" << thisLaneVSafe
1716 <<
" neighLaneVSafe=" << neighLaneVSafe
1717 <<
" relativeGain=" << relativeGain
1718 <<
" blocked=" << blocked
1732 if (thisLaneVSafe > neighLaneVSafe) {
1737 }
else if (thisLaneVSafe == neighLaneVSafe) {
1755 #ifdef DEBUG_WANTS_CHANGE
1761 <<
" thisLaneVSafe=" << thisLaneVSafe
1762 <<
" neighLaneVSafe=" << neighLaneVSafe
1763 <<
" relativeGain=" << relativeGain
1764 <<
" blocked=" << blocked
1770 && (relativeGain > NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1780 && relativeGain >= 0
1781 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1788 #ifdef DEBUG_WANTS_CHANGE
1794 <<
" thisLaneVSafe=" << thisLaneVSafe
1795 <<
" neighLaneVSafe=" << neighLaneVSafe
1806 const MSVehicle* leader = leaderDist.first;
1807 const double gap = leaderDist.second;
1809 if (acceleratingLeader) {
1813 if (leader ==
nullptr) {
1825 if (leader ==
nullptr) {
1836 futureSpeed =
MIN2(vMax, futureSpeed);
1839 const double deltaV = vMax - futureLeaderSpeed;
1840 if (deltaV > 0 && gap > 0) {
1842 const double fullSpeedGap = gap - secGap;
1846 const double gapClosingTime =
MAX2(0.0, fullSpeedGap / deltaV);
1849 futureSpeed =
MIN2(futureSpeed, (gapClosingTime * futureSpeed + (foreCastTime - gapClosingTime) * futureLeaderSpeed) / foreCastTime);
1861 if ((*blocked) !=
nullptr) {
1863 #ifdef DEBUG_SLOW_DOWN
1872 if (gap > POSITION_EPS) {
1886 gap - POSITION_EPS, (*blocked)->getSpeed(),
1887 (*blocked)->getCarFollowModel().getMaxDecel()));
1890 #ifdef DEBUG_SLOW_DOWN
1894 <<
" slowing down for"
1916 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1932 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1944 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1950 <<
" potential=" << potential
1963 #ifdef DEBUG_WANTS_CHANGE
1965 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
1971 if (leader.first != 0) {
1973 v =
MIN2(v, stopSpeed);
1974 #ifdef DEBUG_WANTS_CHANGE
1976 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
1993 #ifdef DEBUG_WANTS_CHANGE
1995 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" myLeftSpace=" <<
myLeftSpace <<
" latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
" result=" << result <<
"\n";
2003 result =
MAX2(-speedBound,
MIN2(speedBound, result));
2020 return myOppositeParam <= 0 ? std::numeric_limits<double>::max() : 1 /
myOppositeParam;
#define HELP_DECEL_FACTOR
#define LOOK_AHEAD_MIN_SPEED
#define LCA_RIGHT_IMPATIENCE
#define REACT_TO_STOPPED_DISTANCE
#define RELGAIN_NORMALIZATION_MIN_SPEED
#define CUT_IN_LEFT_SPEED_THRESHOLD
#define MAX_ONRAMP_LENGTH
#define LOOK_AHEAD_SPEED_MEMORY
#define LC_RESOLUTION_SPEED_LAT
std::pair< const MSPerson *, double > PersonDist
@ SVC_EMERGENCY
public emergency vehicles
LaneChangeAction
The state of a vehicle's lane-change behavior.
@ LCA_KEEPRIGHT
The action is due to the default of keeping right "Rechtsfahrgebot".
@ LCA_BLOCKED
blocked in all directions
@ LCA_URGENT
The action is urgent (to be defined by lc-model)
@ LCA_STAY
Needs to stay on the current lane.
@ LCA_BLOCKED_BY_LEADER
blocked by leader
@ LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
@ LCA_COOPERATIVE
The action is done to help someone else.
@ LCA_LEFT
Wants go to the left.
@ LCA_STRATEGIC
The action is needed to follow the route (navigational lc)
@ LCA_AMBACKBLOCKER_STANDING
@ LCA_TRACI
The action is due to a TraCI request.
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
@ LCA_WANTS_LANECHANGE
lane can change
@ LCA_RIGHT
Wants go to the right.
@ LCA_BLOCKED_BY_FOLLOWER
blocker by follower
@ SUMO_ATTR_LCA_COOPERATIVE_SPEED
@ SUMO_ATTR_LCA_ASSERTIVE
@ SUMO_ATTR_LCA_LOOKAHEADLEFT
@ SUMO_ATTR_LCA_SPEEDGAIN_PARAM
@ SUMO_ATTR_LCA_MAXDISTLATSTANDING
@ SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD
@ SUMO_ATTR_LCA_MAXSPEEDLATFACTOR
@ SUMO_ATTR_LCA_MAXSPEEDLATSTANDING
@ SUMO_ATTR_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_LCA_COOPERATIVE_PARAM
@ SUMO_ATTR_LCA_OPPOSITE_PARAM
@ SUMO_ATTR_LCA_OVERTAKE_RIGHT
@ SUMO_ATTR_LCA_STRATEGIC_PARAM
@ SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME
@ SUMO_ATTR_LCA_EXPERIMENTAL1
@ SUMO_ATTR_LCA_SPEEDGAINRIGHT
int gPrecision
the precision for floating point outputs
#define UNUSED_PARAMETER(x)
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class responsible for exchanging messages between cars involved in lane-change interaction.
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
Interface for lane-change models.
double getForwardPos() const
get vehicle position relative to the forward direction lane
const MSCFModel & getCarFollowModel() const
The vehicle's car following model.
bool hasBlueLight() const
virtual double computeSpeedLat(double latDist, double &maneuverDist, bool urgent) const
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
int myOwnState
The current state of the vehicle.
virtual void prepareStep()
double myMaxDistLatStanding
int & getCanceledState(const int dir)
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
double myMaxSpeedLatFactor
const LaneChangeModel myModel
the type of this model
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
double myMaxSpeedLatStanding
virtual void saveBlockerLength(double length)
reserve space at the end of the lane to avoid dead locks
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
double getImpatience() const
Returns this vehicles impatience.
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
bool isStopped() const
Returns whether the vehicle is at a stop.
The car-following model abstraction.
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)
double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
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...
double maximumSafeStopSpeed(double gap, double decel, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
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...
virtual double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
double maximumSafeFollowSpeed(double gap, double egoSpeed, double predSpeed, double predMaxDecel, bool onInsertion=false) const
Returns the maximum safe velocity for following the given leader.
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)
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
virtual double getSpeedAfterMaxDecel(double v) const
Returns the velocity after maximum deceleration.
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
bool hasLaneChanger() const
bool isInternal() const
return whether this edge is an internal edge
static bool gSemiImplicitEulerUpdate
static double getRoundaboutDistBonus(const MSVehicle &veh, double bonusParam, 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...
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &follower, 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) override
Called to examine whether the vehicle wants to change using the given laneOffset. This method gets th...
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
double computeSpeedLat(double latDist, double &maneuverDist, bool urgent) const override
decides the next lateral speed (for continuous lane changing)
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
bool debugVehicle() const override
whether the current vehicles shall be debugged
double getAssumedDecelForLaneChangeDuration() const override
Returns a deceleration value which is used for the estimation of the duration of a lane change.
double mySpeedGainLookahead
const double myExperimentalParam1
double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel) override
Called to adapt the speed in order to allow a lane change. It uses information on LC-related desired ...
void initDerivedParameters()
init cached parameters derived directly from model parameters
double myCooperativeParam
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()
MSLCM_LC2013(MSVehicle &v)
double myChangeProbThresholdRight
double anticipateFollowSpeed(const std::pair< MSVehicle *, double > &leaderDist, double dist, double vMax, bool acceleratingLeader)
anticipate future follow speed for the given leader
std::string getParameter(const std::string &key) const override
try to retrieve the given parameter from this device. Throw exception for unsupported key
void setParameter(const std::string &key, const std::string &value) override
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
double myCooperativeSpeed
double informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighLead, double remainingSeconds)
double myLeadingBlockerLength
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
void prepareStep() override
double getSafetyFactor() const override
return factor for modifying the safety constraints of the car-following model
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
bool amBlockingFollowerPlusNB()
double myKeepRightProbability
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
void adaptSpeedToPedestrians(const MSLane *lane, double &v)
react to pedestrians on the given lane
double getOppositeSafetyFactor() const override
return factor for modifying the safety constraints for opposite-diretction overtaking of the car-foll...
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
double myKeepRightAcceptanceTime
double myOvertakeRightParam
double mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial
double myChangeProbThresholdLeft
void * inform(void *info, MSVehicle *sender) override
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
int _wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &follower, 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
static double overtakeDistance(const MSVehicle *follower, const MSVehicle *leader, const double gap, double followerSpeed=INVALID_SPEED, double leaderSpeed=INVALID_SPEED)
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
std::pair< const MSPerson *, double > nextBlocking(double minPos, double minRight, double maxLeft, double stopTime=0) const
This is just a wrapper around MSPModel::nextBlocking. You should always check using hasPedestrians be...
bool isAccelLane() const
return whether this lane is an acceleration lane
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
double getLength() const
Returns the lane's length.
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
bool hasPedestrians() const
whether the lane has pedestrians on it
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
MSEdge & getEdge() const
Returns the lane's edge.
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
const MSLane * lane
The lane to stop at (microsim only)
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Representation of a vehicle in the micro simulation.
MSAbstractLaneChangeModel & getLaneChangeModel()
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation,...
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
int getBestLaneOffset() const
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
Influencer & getInfluencer()
double getRightSideOnLane() const
Get the vehicle's lateral position on the lane:
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getSpeed() const
Returns the vehicle's current speed.
double getPositionOnLane() const
Get the vehicle's position along the lane.
const MSLane * getLane() const
Returns the lane the vehicle is on.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane
void setLateralPositionOnLane(double posLat)
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double getMinGap() const
Get the free space in front of vehicles of this class.
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
double getLength() const
Get vehicle's length [m].
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
void step(double dt)
evolve for a time step of length dt.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
A structure representing the best lanes for continuing the current route starting at 'lane'.
double length
The overall length which may be driven when using this lane without a lane change.
std::vector< MSLane * > bestContinuations
MSLane * lane
The described lane.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive.
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.