46 #define LOOK_FORWARD 10.
50 #define LCA_RIGHT_IMPATIENCE -1.
51 #define CUT_IN_LEFT_SPEED_THRESHOLD 27.
53 #define LOOK_AHEAD_MIN_SPEED 0.0
54 #define LOOK_AHEAD_SPEED_MEMORY 0.9
56 #define HELP_DECEL_FACTOR 1.0
58 #define HELP_OVERTAKE (10.0 / 3.6)
59 #define MIN_FALLBEHIND (7.0 / 3.6)
61 #define RELGAIN_NORMALIZATION_MIN_SPEED 10.0
63 #define OPPOSITE_URGENCY 5.0
65 #define KEEP_RIGHT_TIME 5.0
66 #define KEEP_RIGHT_ACCEPTANCE 7.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),
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.;
236 double nVSafe = wanted;
241 #ifdef DEBUG_PATCH_SPEED
252 #ifdef DEBUG_PATCH_SPEED
254 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe + NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
257 nVSafe =
MAX2(min, safe);
275 nVSafe =
MIN2(v * coopWeight + (1 - coopWeight) * wanted, nVSafe);
277 #ifdef DEBUG_PATCH_SPEED
284 #ifdef DEBUG_PATCH_SPEED
286 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
290 #ifdef DEBUG_PATCH_SPEED
292 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
300 #ifdef DEBUG_PATCH_SPEED
313 #ifdef DEBUG_PATCH_SPEED
318 return (max + wanted) / 2.0;
322 #ifdef DEBUG_PATCH_SPEED
328 return (
MAX2(0., min) + wanted) / 2.0;
334 #ifdef DEBUG_PATCH_SPEED
339 return (max + wanted) / 2.0;
380 #ifdef DEBUG_PATCH_SPEED
385 return (max + wanted) / 2.0;
389 #ifdef DEBUG_PATCH_SPEED
417 #ifdef DEBUG_INFORMED
421 <<
" informedBy=" << sender->
getID()
422 <<
" info=" << pinfo->second
423 <<
" vSafe=" << pinfo->first
435 double overtakeDist = (gap
440 return MAX2(overtakeDist, 0.);
448 const std::pair<MSVehicle*, double>& neighLead,
449 double remainingSeconds) {
458 #ifdef DEBUG_INFORMER
460 std::cout <<
"\nINFORM_LEADER"
465 const MSVehicle*
const nv = neighLead.first;
473 neighNextGap = neighLead.second +
SPEED2DIST(neighNextSpeed - plannedSpeed);
478 #ifdef DEBUG_INFORMER
480 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
487 const double dv = plannedSpeed - nv->
getSpeed();
490 overtakeTime = overtakeDist / dv;
493 overtakeTime = remainingSeconds + 1;
496 #ifdef DEBUG_INFORMER
499 <<
"\nnv = " << nv->
getID()
500 <<
"\nplannedSpeed = " << plannedSpeed
501 <<
"\nleaderSpeed = " << nv->
getSpeed()
503 <<
"\nremainingSeconds = " << remainingSeconds
504 <<
"\novertakeDist = " << overtakeDist
505 <<
"\novertakeTime = " << overtakeTime
520 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
525 const double targetSpeed =
MAX2(
534 #ifdef DEBUG_INFORMER
537 <<
" cannot overtake leader nv=" << nv->
getID()
541 <<
" overtakeDist=" << overtakeDist
542 <<
" overtakeTime=" << overtakeTime
543 <<
" remainingSeconds=" << remainingSeconds
544 <<
" currentGap=" << neighLead.second
546 <<
" neighNextSpeed=" << neighNextSpeed
547 <<
" neighNextGap=" << neighNextGap
548 <<
" targetSpeed=" << targetSpeed
549 <<
" nextSpeed=" << nextSpeed
557 #ifdef DEBUG_INFORMER
560 <<
" cannot overtake fast leader nv=" << nv->
getID()
564 <<
" overtakeDist=" << overtakeDist
566 <<
" overtakeTime=" << overtakeTime
567 <<
" remainingSeconds=" << remainingSeconds
568 <<
" currentGap=" << neighLead.second
569 <<
" targetSpeed=" << targetSpeed
578 #ifdef DEBUG_INFORMER
581 <<
" wants to overtake leader nv=" << nv->
getID()
583 <<
" overtakeDist=" << overtakeDist
584 <<
" remainingSeconds=" << remainingSeconds
585 <<
" overtakeTime=" << overtakeTime
586 <<
" currentGap=" << neighLead.second
596 const double targetSpeed =
MAX2(
600 #ifdef DEBUG_INFORMER
602 std::cout <<
" not blocked by leader nv=" << nv->
getID()
604 <<
" gap=" << neighLead.second
605 <<
" neighNextSpeed=" << neighNextSpeed
606 <<
" neighNextGap=" << neighNextGap
608 <<
" targetSpeed=" << targetSpeed
612 return MIN2(targetSpeed, plannedSpeed);
620 const std::pair<MSVehicle*, double>& neighFollow,
621 double remainingSeconds,
622 double plannedSpeed) {
627 #ifdef DEBUG_INFORMER
629 std::cout <<
"\nINFORM_FOLLOWER"
635 #ifdef DEBUG_INFORMER
637 std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
645 if ((neededGap - neighFollow.second) / remainingSeconds < (
MAX2(plannedSpeed, 0.) - nv->
getSpeed())) {
646 #ifdef DEBUG_INFORMER
648 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help." <<
"\nneededGap = " << neededGap <<
"\n";
668 double neighNewSpeed;
670 double neighNewSpeed1s;
680 dv = plannedSpeed - neighNewSpeed1s;
687 decelGap = neighFollow.second + dv;
694 neighNewSpeed1s = nv->
getSpeed() - helpDecel;
706 #ifdef DEBUG_INFORMER
710 <<
" plannedSpeed=" << plannedSpeed
711 <<
" threshold=" << onRampThreshold
712 <<
" neighNewSpeed=" << neighNewSpeed
713 <<
" neighNewSpeed1s=" << neighNewSpeed1s
715 <<
" gap=" << neighFollow.second
716 <<
" decelGap=" << decelGap
717 <<
" secureGap=" << secureGap
724 && neighNewSpeed1s < onRampThreshold) {
728 if (decelGap > 0 && decelGap >= secureGap) {
736 double vsafe, vsafe1;
756 #ifdef DEBUG_INFORMER
758 std::cout <<
"nextGap=" << nextGap <<
" (without help decel) \n";
766 MAX2(0., plannedSpeed),
774 nv->
getSpeed(), plannedAccel, -decel2,
784 MAX2(0., plannedSpeed),
787 assert(vsafe >= vsafe1 - NUMERICAL_EPS);
789 #ifdef DEBUG_INFORMER
791 std::cout <<
"nextGap=" << nextGap
792 <<
" (with vsafe1 and help decel) \nvsafe1=" << vsafe1
793 <<
" vsafe=" << vsafe
802 if (nextGap < nextSecureGap) {
804 vsafe = neighNewSpeed;
807 #ifdef DEBUG_INFORMER
809 std::cout <<
"nextGap=" << nextGap
810 <<
" minNextSecureGap=" << nextSecureGap
811 <<
" vsafe=" << vsafe <<
"\n";
819 #ifdef DEBUG_INFORMER
821 std::cout <<
" wants to cut in before nv=" << nv->
getID()
822 <<
" vsafe1=" << vsafe1 <<
" vsafe=" << vsafe
848 #ifdef DEBUG_INFORMER
850 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
857 #ifdef DEBUG_INFORMER
859 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
878 #ifdef DEBUG_INFORMER
882 std::cout <<
" wants right follower to slow down a bit\n";
889 #ifdef DEBUG_INFORMER
892 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
914 if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) {
915 #ifdef DEBUG_INFORMER
917 std::cout <<
" wants to cut in before follower nv=" << nv->
getID() <<
" (eventually)\n";
930 #ifdef DEBUG_INFORMER
934 <<
" informs follower " << nv->
getID()
935 <<
" vhelp=" << vhelp
944 const double needDV = overtakeDist / remainingSeconds;
948 #ifdef DEBUG_INFORMER
952 <<
" wants to be overtaken by=" << nv->
getID()
953 <<
" overtakeDist=" << overtakeDist
955 <<
" vhelp=" << vhelp
956 <<
" needDV=" << needDV
965 double vsafe, vsafe1;
979 double anticipationTime = 1.;
990 if (anticipatedGap > secureGap) {
997 if (anticipatedGap < secureGap) {
1008 #ifdef DEBUG_INFORMER
1010 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
1065 const std::pair<MSVehicle*, double>& leader,
1066 const std::pair<MSVehicle*, double>& neighLead,
1067 const std::pair<MSVehicle*, double>& neighFollow,
1069 const std::vector<MSVehicle::LaneQ>& preb,
1072 assert(laneOffset == 1 || laneOffset == -1);
1076 int bestLaneOffset = 0;
1081 double currentDist = 0;
1082 double neighDist = 0;
1091 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1092 for (
int p = 0; p < (int) preb.size(); ++p) {
1093 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1094 assert(p + prebOffset < (
int)preb.size());
1096 neigh = preb[p + prebOffset];
1097 currentDist = curr.
length;
1098 neighDist = neigh.
length;
1100 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1101 #ifdef DEBUG_WANTS_CHANGE
1105 <<
" bestLaneOffsetOld=" << bestLaneOffset
1106 <<
" bestLaneOffsetNew=" << laneOffset
1110 bestLaneOffset = prebOffset;
1112 best = preb[p + bestLaneOffset];
1118 const bool right = (laneOffset == -1);
1120 neigh = preb[preb.size() - 1];
1123 bestLaneOffset = -1;
1125 neighDist = neigh.
length;
1126 currentDist = curr.
length;
1128 double driveToNextStop = -std::numeric_limits<double>::max();
1136 #ifdef DEBUG_WANTS_CHANGE
1141 <<
" stopPos=" << stopPos
1142 <<
" currentDist=" << currentDist
1143 <<
" neighDist=" << neighDist
1147 currentDist =
MAX2(currentDist, stopPos);
1148 neighDist =
MAX2(neighDist, stopPos);
1154 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1160 if (lastBlocked != firstBlocked) {
1164 #ifdef DEBUG_WANTS_CHANGE
1173 <<
" leaderGap=" << leader.second
1175 <<
" neighLeadGap=" << neighLead.second
1177 <<
" neighFollowGap=" << neighFollow.second
1200 assert(memoryFactor > 0.);
1208 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped() && leader.second < (currentDist - posOnLane)) {
1213 + leader.first->getVehicleType().getLengthWithGap()
1215 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped() && neighLead.second < (currentDist - posOnLane)) {
1218 + neighLead.first->getVehicleType().getLengthWithGap()
1219 + neighLead.second);
1237 currentDist += roundaboutBonus;
1238 neighDist += roundaboutBonus;
1242 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1243 const double neighLeftPlace =
MAX2(0.0, neighDist - posOnLane - maxJam);
1246 double thisLaneVSafe = vMax;
1252 #ifdef DEBUG_WANTS_CHANGE
1257 <<
" laDist=" << laDist
1258 <<
" currentDist=" << currentDist
1259 <<
" usableDist=" << usableDist
1260 <<
" bestLaneOffset=" << bestLaneOffset
1262 <<
" best.length=" << best.
length
1263 <<
"\n roundaboutBonus=" << roundaboutBonus
1264 <<
" maxJam=" << maxJam
1265 <<
" neighDist=" << neighDist
1266 <<
" neighLeftPlace=" << neighLeftPlace
1271 bool changeLeftToAvoidOvertakeRight =
false;
1278 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1290 if (vSafeFollow >= vMaxDecel) {
1291 vSafe = vSafeFollow;
1293 vSafe =
MAX2(vMaxDecel, vStayBehind);
1298 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1301 const double deltaGapFuture = deltaV * 8;
1304 if (vSafeFuture < vSafe) {
1305 const double relativeGain = deltaV /
MAX2(vMax,
1308 changeLeftToAvoidOvertakeRight =
true;
1310 #ifdef DEBUG_WANTS_CHANGE
1313 <<
" avoid overtaking on the right nv=" << nv->
getID()
1314 <<
" deltaV=" << deltaV
1323 const double overtakeDist = (leader.first == 0 ? -1 :
1327 &&
MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1329 && (!checkOverTakeRight || !right)
1330 && (neighLead.first == 0 || !neighLead.first->isStopped()
1332 || neighLead.second > overtakeDist)) {
1335 #ifdef DEBUG_WANTS_CHANGE
1337 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" overtake stopped leader=" << leader.first->getID()
1338 <<
" overtakeDist=" << overtakeDist
1339 <<
" remaining=" <<
MIN2(neighDist, currentDist) - posOnLane
1344 }
else if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1351 #ifdef DEBUG_WANTS_CHANGE
1353 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1357 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1362 #ifdef DEBUG_WANTS_CHANGE
1364 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1368 }
else if (bestLaneOffset == 0
1369 && (leader.first == 0 || !leader.first->isStopped())
1371 && roundaboutBonus == 0
1377 #ifdef DEBUG_WANTS_CHANGE
1379 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1386 #ifdef DEBUG_WANTS_CHANGE
1394 if ((ret & lcaCounter) != 0) {
1398 #ifdef DEBUG_WANTS_CHANGE
1400 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
1411 if (changeToBest && abs(bestLaneOffset) > 1) {
1414 #ifdef DEBUG_WANTS_CHANGE
1416 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1424 if (*firstBlocked != neighLead.first) {
1428 const int remainingLanes =
MAX2(1, abs(bestLaneOffset));
1430 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1434 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1439 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1442 #ifdef DEBUG_WANTS_CHANGE
1447 <<
" remainingSeconds=" << remainingSeconds
1448 <<
" plannedSpeed=" << plannedSpeed
1456 const double inconvenience =
MIN2(1.0, (laneOffset < 0
1463 if (roundaboutBonus > 0) {
1465 #ifdef DEBUG_WANTS_CHANGE
1469 <<
" roundaboutBonus=" << roundaboutBonus
1499 #ifdef DEBUG_WANTS_CHANGE
1501 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1521 && (!speedGainInconvenient)
1523 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1526 #ifdef DEBUG_COOPERATE
1530 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1532 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1559 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1560 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1572 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1575 #ifdef DEBUG_WANTS_CHANGE
1579 <<
" currentDist=" << currentDist
1580 <<
" neighDist=" << neighDist
1581 <<
" thisVSafe=" << thisLaneVSafe
1582 <<
" neighVSafe=" << neighLaneVSafe
1583 <<
" relGain=" <<
toString(relativeGain, 8)
1590 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1607 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1616 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1617 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1618 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1620 vMax, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1621 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1624 if (checkOverTakeRight && leader.first != 0
1625 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1626 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1627 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1628 const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1637 #ifdef DEBUG_WANTS_CHANGE
1642 <<
" neighDist=" << neighDist
1644 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1646 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1647 <<
" acceptanceTime=" << acceptanceTime
1648 <<
" fullSpeedGap=" << fullSpeedGap
1649 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1650 <<
" dProb=" << deltaProb
1663 #ifdef DEBUG_WANTS_CHANGE
1669 <<
" thisLaneVSafe=" << thisLaneVSafe
1670 <<
" neighLaneVSafe=" << neighLaneVSafe
1671 <<
" relativeGain=" << relativeGain
1672 <<
" blocked=" << blocked
1686 if (thisLaneVSafe > neighLaneVSafe) {
1691 }
else if (thisLaneVSafe == neighLaneVSafe) {
1709 #ifdef DEBUG_WANTS_CHANGE
1715 <<
" thisLaneVSafe=" << thisLaneVSafe
1716 <<
" neighLaneVSafe=" << neighLaneVSafe
1717 <<
" relativeGain=" << relativeGain
1718 <<
" blocked=" << blocked
1724 && (relativeGain > NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1734 && relativeGain >= 0
1735 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1742 #ifdef DEBUG_WANTS_CHANGE
1748 <<
" thisLaneVSafe=" << thisLaneVSafe
1749 <<
" neighLaneVSafe=" << neighLaneVSafe
1760 const MSVehicle* leader = leaderDist.first;
1761 const double gap = leaderDist.second;
1763 if (acceleratingLeader) {
1767 if (leader ==
nullptr) {
1774 if (leader ==
nullptr) {
1780 futureSpeed =
MIN2(vMax, futureSpeed);
1783 const double deltaV = vMax - futureLeaderSpeed;
1784 if (deltaV > 0 && gap > 0) {
1786 const double fullSpeedGap = gap - secGap;
1790 const double gapClosingTime = fullSpeedGap / deltaV;
1793 futureSpeed =
MIN2(futureSpeed, (gapClosingTime * futureSpeed + (foreCastTime - gapClosingTime) * futureLeaderSpeed) / foreCastTime);
1805 if ((*blocked) !=
nullptr) {
1807 #ifdef DEBUG_SLOW_DOWN
1816 if (gap > POSITION_EPS) {
1830 gap - POSITION_EPS, (*blocked)->getSpeed(),
1831 (*blocked)->getCarFollowModel().getMaxDecel()));
1834 #ifdef DEBUG_SLOW_DOWN
1838 <<
" slowing down for"
1860 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1876 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1888 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1894 <<
" potential=" << potential
1907 #ifdef DEBUG_WANTS_CHANGE
1909 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
1915 if (leader.first != 0) {
1917 v =
MIN2(v, stopSpeed);
1918 #ifdef DEBUG_WANTS_CHANGE
1920 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
1938 std::cout <<
" myLeftSpace=" <<
myLeftSpace <<
" latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
"result1=" << result <<
"\n";
1945 result =
MAX2(-speedBound,
MIN2(speedBound, result));
1962 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 KEEP_RIGHT_ACCEPTANCE
#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_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD
@ 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_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.
int myOwnState
The current state of the vehicle.
virtual void prepareStep()
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
virtual double computeSpeedLat(double latDist, double &maneuverDist) const
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
const MSCFModel & myCarFollowModel
The vehicle's car following model.
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.
std::mt19937 * getRNG() const
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)
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...
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...
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 maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
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 brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
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.
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)
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)
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) const
decides the next lateral speed (for continuous lane changing)
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
double mySpeedGainLookahead
const double myExperimentalParam1
void initDerivedParameters()
init cached parameters derived directly from model parameters
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...
double myCooperativeParam
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()
MSLCM_LC2013(MSVehicle &v)
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
double myChangeProbThresholdRight
double anticipateFollowSpeed(const std::pair< MSVehicle *, double > &leaderDist, double dist, double vMax, bool acceleratingLeader)
anticipate future follow speed for the given leader
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
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
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
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
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 setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
bool debugVehicle() const
whether the current vehicles shall be debugged
double myOvertakeRightParam
double mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial
double getOppositeSafetyFactor() const
return factor for modifying the safety constraints for opposite-diretction overtaking of the car-foll...
void * inform(void *info, MSVehicle *sender)
double myChangeProbThresholdLeft
double getAssumedDecelForLaneChangeDuration() const
Returns a deceleration value which is used for the estimation of the duration of a lane change.
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
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 ...
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 getOppositePos(double pos) const
return the corresponding position on the opposite lane
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
MSEdge & getEdge() const
Returns the lane's edge.
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 getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
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.
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 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(std::mt19937 *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.