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 65 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 66 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 67 #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) 69 #define ROUNDABOUT_DIST_FACTOR (double)10.0 // Must be >=1.0, serves an alternative way of decreasing sense lc-urgency by multiplying the distance along the next roundabout 70 #define ROUNDABOUT_DIST_TRESH (double)10.0 // roundabout distances below ROUNDABOUT_DIST_TRESH are not multiplied by ROUNDABOUT_DIST_FACTOR 72 #define KEEP_RIGHT_HEADWAY (double)2.0 73 #define MAX_ONRAMP_LENGTH (double)200. 74 #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 76 #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 77 #define LC_ASSUMED_DECEL (double)1.0 // the minimal constant deceleration assumed to estimate the duration of a continuous lane-change at its initiation. 79 #define REACT_TO_STOPPED_DISTANCE 100 94 #define DEBUG_COND (myVehicle.isSelected()) 102 mySpeedGainProbability(0),
103 myKeepRightProbability(0),
104 myLeadingBlockerLength(0),
116 #ifdef DEBUG_CONSTRUCTOR 152 const std::pair<MSVehicle*, double>& leader,
153 const std::pair<MSVehicle*, double>& neighLead,
154 const std::pair<MSVehicle*, double>& neighFollow,
156 const std::vector<MSVehicle::LaneQ>& preb,
160 #ifdef DEBUG_WANTS_CHANGE 162 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 169 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
174 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
176 #ifdef DEBUG_WANTS_CHANGE 189 #ifdef DEBUG_PATCH_SPEED 191 std::cout <<
"\nPATCH_SPEED\n" 198 <<
" wanted=" << wanted
205 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
207 #ifdef DEBUG_PATCH_SPEED 209 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
222 #ifdef DEBUG_PATCH_SPEED 229 <<
" wanted=" << wanted << std::endl;
234 double MAGIC_offset = 1.;
238 #ifdef DEBUG_PATCH_SPEED 249 #ifdef DEBUG_PATCH_SPEED 251 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
254 return MAX2(min, safe);
259 double nVSafe = wanted;
274 #ifdef DEBUG_PATCH_SPEED 281 #ifdef DEBUG_PATCH_SPEED 283 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
287 #ifdef DEBUG_PATCH_SPEED 289 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
297 #ifdef DEBUG_PATCH_SPEED 310 #ifdef DEBUG_PATCH_SPEED 315 return (max + wanted) / (double) 2.0;
319 #ifdef DEBUG_PATCH_SPEED 325 return (
MAX2(0., min) + wanted) / (double) 2.0;
331 #ifdef DEBUG_PATCH_SPEED 336 return (max + wanted) / (double) 2.0;
377 #ifdef DEBUG_PATCH_SPEED 382 return (max + wanted) / (double) 2.0;
386 #ifdef DEBUG_PATCH_SPEED 414 #ifdef DEBUG_INFORMED 418 <<
" informedBy=" << sender->
getID()
419 <<
" info=" << pinfo->second
420 <<
" vSafe=" << pinfo->first
432 double overtakeDist = (gap
437 return MAX2(overtakeDist, 0.);
445 const std::pair<MSVehicle*, double>& neighLead,
446 double remainingSeconds) {
455 #ifdef DEBUG_INFORMER 457 std::cout <<
"\nINFORM_LEADER" 464 #ifdef DEBUG_INFORMER 466 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 473 const double dv = plannedSpeed - nv->
getSpeed();
476 overtakeTime = overtakeDist / dv;
479 overtakeTime = remainingSeconds + 1;
482 #ifdef DEBUG_INFORMER 485 <<
"\nnv = " << nv->
getID()
486 <<
"\nplannedSpeed = " << plannedSpeed
487 <<
"\nleaderSpeed = " << nv->
getSpeed()
489 <<
"\nremainingSeconds = " << remainingSeconds
490 <<
"\novertakeDist = " << overtakeDist
491 <<
"\novertakeTime = " << overtakeTime
506 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
518 #ifdef DEBUG_INFORMER 521 <<
" cannot overtake leader nv=" << nv->
getID()
525 <<
" overtakeDist=" << overtakeDist
526 <<
" overtakeTime=" << overtakeTime
527 <<
" remainingSeconds=" << remainingSeconds
528 <<
" currentGap=" << neighLead.second
531 <<
" targetSpeed=" << targetSpeed
532 <<
" nextSpeed=" << nextSpeed
540 #ifdef DEBUG_INFORMER 543 <<
" cannot overtake fast leader nv=" << nv->
getID()
547 <<
" overtakeDist=" << overtakeDist
549 <<
" overtakeTime=" << overtakeTime
550 <<
" remainingSeconds=" << remainingSeconds
551 <<
" currentGap=" << neighLead.second
552 <<
" targetSpeed=" << targetSpeed
561 #ifdef DEBUG_INFORMER 564 <<
" wants to overtake leader nv=" << nv->
getID()
566 <<
" overtakeDist=" << overtakeDist
567 <<
" remainingSeconds=" << remainingSeconds
568 <<
" overtakeTime=" << overtakeTime
569 <<
" currentGap=" << neighLead.second
577 }
else if (neighLead.first != 0) {
580 double dv, nextNVSpeed;
598 #ifdef DEBUG_INFORMER 600 std::cout <<
" not blocked by leader nv=" << nv->
getID()
602 <<
" gap=" << neighLead.second
603 <<
" nextGap=" << neighLead.second - dv
605 <<
" targetSpeed=" << targetSpeed
609 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;
745 assert(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),
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";
1054 const std::pair<MSVehicle*, double>& leader,
1055 const std::pair<MSVehicle*, double>& neighLead,
1056 const std::pair<MSVehicle*, double>& neighFollow,
1058 const std::vector<MSVehicle::LaneQ>& preb,
1061 assert(laneOffset == 1 || laneOffset == -1);
1065 int bestLaneOffset = 0;
1070 double currentDist = 0;
1071 double neighDist = 0;
1080 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1081 for (
int p = 0; p < (int) preb.size(); ++p) {
1082 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1083 assert(p + prebOffset < (
int)preb.size());
1085 neigh = preb[p + prebOffset];
1086 currentDist = curr.
length;
1087 neighDist = neigh.
length;
1088 bestLaneOffset = curr.bestLaneOffset;
1089 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1090 #ifdef DEBUG_WANTS_CHANGE 1094 <<
" bestLaneOffsetOld=" << bestLaneOffset
1095 <<
" bestLaneOffsetNew=" << laneOffset
1099 bestLaneOffset = prebOffset;
1101 best = preb[p + bestLaneOffset];
1107 const bool right = (laneOffset == -1);
1109 neigh = preb[preb.size() - 1];
1112 bestLaneOffset = -1;
1114 neighDist = neigh.
length;
1115 currentDist = curr.
length;
1121 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1127 if (lastBlocked != firstBlocked) {
1131 #ifdef DEBUG_WANTS_CHANGE 1140 <<
" leaderGap=" << leader.second
1142 <<
" neighLeadGap=" << neighLead.second
1144 <<
" neighFollowGap=" << neighFollow.second
1167 assert(memoryFactor > 0.);
1175 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped()) {
1180 + leader.first->getVehicleType().getLengthWithGap());
1181 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped()) {
1184 + neighLead.first->getVehicleType().getLengthWithGap();
1200 double roundaboutDistanceAhead = 0;
1201 double roundaboutDistanceAheadNeigh = 0;
1202 int roundaboutEdgesAhead = 0;
1203 int roundaboutEdgesAheadNeigh = 0;
1205 getRoundaboutAheadInfo(
this, curr, neigh, roundaboutDistanceAhead, roundaboutDistanceAheadNeigh, roundaboutEdgesAhead, roundaboutEdgesAheadNeigh);
1209 neighDist +=
roundaboutDistBonus(roundaboutDistanceAheadNeigh, roundaboutEdgesAheadNeigh);
1211 #ifdef DEBUG_WANTS_CHANGE 1213 if (roundaboutEdgesAhead > 0) {
1214 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1222 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1223 const double neighLeftPlace =
MAX2((
double) 0, neighDist - posOnLane - maxJam);
1226 double thisLaneVSafe = vMax;
1231 #ifdef DEBUG_WANTS_CHANGE 1236 <<
" laDist=" << laDist
1237 <<
" currentDist=" << currentDist
1238 <<
" usableDist=" << usableDist
1239 <<
" bestLaneOffset=" << bestLaneOffset
1241 <<
" best.length=" << best.
length 1242 <<
" maxJam=" << maxJam
1243 <<
" neighLeftPlace=" << neighLeftPlace
1248 bool changeLeftToAvoidOvertakeRight =
false;
1255 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1262 double vSafe =
MAX2(
1269 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1272 const double deltaGapFuture = deltaV * 8;
1275 if (vSafeFuture < vSafe) {
1276 const double relativeGain = deltaV /
MAX2(vMax,
1279 changeLeftToAvoidOvertakeRight =
true;
1281 #ifdef DEBUG_WANTS_CHANGE 1284 <<
" avoid overtaking on the right nv=" << nv->
getID()
1285 <<
" deltaV=" << deltaV
1294 const double overtakeDist = (leader.first == 0 ? -1 :
1298 &&
MIN2(neighDist, currentDist) - posOnLane > overtakeDist
1300 && (!checkOverTakeRight || !right)
1301 && (neighLead.first == 0 || !neighLead.first->isStopped()
1303 || neighLead.second > overtakeDist)) {
1307 }
else if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1314 #ifdef DEBUG_WANTS_CHANGE 1316 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1320 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1325 #ifdef DEBUG_WANTS_CHANGE 1327 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1331 }
else if (bestLaneOffset == 0
1332 && (leader.first == 0 || !leader.first->isStopped())
1334 && roundaboutEdgesAhead == 0
1340 #ifdef DEBUG_WANTS_CHANGE 1342 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1349 #ifdef DEBUG_WANTS_CHANGE 1357 if ((ret & lcaCounter) != 0) {
1361 #ifdef DEBUG_WANTS_CHANGE 1363 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
1374 if (changeToBest && abs(bestLaneOffset) > 1) {
1377 #ifdef DEBUG_WANTS_CHANGE 1379 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1387 if (*firstBlocked != neighLead.first) {
1391 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1395 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1400 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1403 #ifdef DEBUG_WANTS_CHANGE 1408 <<
" remainingSeconds=" << remainingSeconds
1409 <<
" plannedSpeed=" << plannedSpeed
1417 const double inconvenience =
MIN2((
double)1.0, (laneOffset < 0
1424 if (roundaboutEdgesAhead > 1) {
1426 #ifdef DEBUG_WANTS_CHANGE 1430 <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead
1460 #ifdef DEBUG_WANTS_CHANGE 1462 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1482 && (!speedGainInconvenient)
1484 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1487 #ifdef DEBUG_COOPERATE 1491 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1493 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1522 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1523 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1525 if (acceleratingLeader) {
1532 if (neighLead.first == 0) {
1536 &
myVehicle, correctedSpeed, neighLead.second, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1538 if (leader.first == 0) {
1542 &
myVehicle, correctedSpeed, leader.second, leader.first->
getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1545 if (neighLead.first == 0) {
1549 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel(),
true));
1551 if (leader.first == 0) {
1555 leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel(),
true));
1565 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1568 #ifdef DEBUG_WANTS_CHANGE 1572 <<
" currentDist=" << currentDist
1573 <<
" neighDist=" << neighDist
1574 <<
" thisVSafe=" << thisLaneVSafe
1575 <<
" neighVSafe=" << neighLaneVSafe
1576 <<
" relGain=" <<
toString(relativeGain, 8)
1583 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1600 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1609 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1610 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1611 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1613 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1614 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1617 if (checkOverTakeRight && leader.first != 0
1618 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1619 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1620 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1621 const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1630 #ifdef DEBUG_WANTS_CHANGE 1635 <<
" neighDist=" << neighDist
1637 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1639 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1640 <<
" acceptanceTime=" << acceptanceTime
1641 <<
" fullSpeedGap=" << fullSpeedGap
1642 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1643 <<
" dProb=" << deltaProb
1656 #ifdef DEBUG_WANTS_CHANGE 1662 <<
" thisLaneVSafe=" << thisLaneVSafe
1663 <<
" neighLaneVSafe=" << neighLaneVSafe
1664 <<
" relativeGain=" << relativeGain
1665 <<
" blocked=" << blocked
1679 if (thisLaneVSafe > neighLaneVSafe) {
1684 }
else if (thisLaneVSafe == neighLaneVSafe) {
1702 #ifdef DEBUG_WANTS_CHANGE 1708 <<
" thisLaneVSafe=" << thisLaneVSafe
1709 <<
" neighLaneVSafe=" << neighLaneVSafe
1710 <<
" relativeGain=" << relativeGain
1711 <<
" blocked=" << blocked
1717 && (relativeGain >
NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1727 && relativeGain >= 0
1728 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1735 #ifdef DEBUG_WANTS_CHANGE 1741 <<
" thisLaneVSafe=" << thisLaneVSafe
1742 <<
" neighLaneVSafe=" << neighLaneVSafe
1753 double& roundaboutDistanceAhead,
double& roundaboutDistanceAheadNeigh,
int& roundaboutEdgesAhead,
int& roundaboutEdgesAheadNeigh) {
1765 roundaboutDistanceAheadNeigh = 0;
1766 double neighPosition = pos;
1776 if (*i != 0 && *i != veh.
getLane()) {
1781 assert(nextLane != 0);
1790 #ifdef DEBUG_WANTS_CHANGE 1792 std::cout <<
"roundaboutDistanceAhead = " << roundaboutDistanceAhead
1793 <<
" roundaboutDistanceAheadNeigh = " << roundaboutDistanceAheadNeigh
1800 roundaboutEdgesAhead = 0;
1802 const MSLane* lane = *it;
1804 roundaboutEdgesAhead += 1;
1805 }
else if (roundaboutEdgesAhead > 0) {
1810 roundaboutEdgesAheadNeigh = 0;
1812 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
1813 roundaboutEdgesAheadNeigh += 1;
1814 }
else if (roundaboutEdgesAheadNeigh > 0) {
1831 if (roundaboutEdgesAhead > 1) {
1854 for (std::vector<MSLane*>::const_iterator i = continuationLanes.begin(); i != continuationLanes.end(); i++) {
1855 assert((*i) == 0 || !(*i)->getEdge().isInternal());
1859 bool encounteredRoundabout =
false;
1860 double roundaboutDistanceAhead = 0.;
1863 std::vector<MSLane*>::const_iterator j = continuationLanes.begin();
1864 while (j != continuationLanes.end() && *j == 0) {
1869 if (j == continuationLanes.end()) {
1871 assert(initialLane == 0);
1873 }
else if (initialLane == 0) {
1878 }
else if (!initialLane->
isInternal() && initialLane != *j) {
1885 assert(position >= 0. && position <= initialLane->getLength());
1887 assert(initialLane == *j);
1888 roundaboutDistanceAhead += initialLane->
getLength() - position;
1889 if (j + 1 == continuationLanes.end() || *(j + 1) == 0 || !(*(j + 1))->getEdge().isRoundabout()) {
1893 const MSLane* nextLane = *(j + 1);
1901 roundaboutDistanceAhead += initialLane->
getLength() - position;
1903 roundaboutDistanceAhead += initialLane->
getLinkCont()[0]->getInternalLengthsAfter();
1908 for (std::vector<MSLane*>::const_iterator it = j; it != continuationLanes.end(); ++it) {
1909 const MSLane* lane = *it;
1912 encounteredRoundabout =
true;
1914 roundaboutDistanceAhead += lane->
getLength();
1919 if (it + 1 != continuationLanes.end() && *(it + 1) != 0 && (*(it + 1))->getEdge().isRoundabout()) {
1924 roundaboutDistanceAhead += linkLength;
1926 }
else if (encounteredRoundabout) {
1931 return roundaboutDistanceAhead;
1939 if ((*blocked) != 0) {
1941 #ifdef DEBUG_SLOW_DOWN 1965 (*blocked)->getCarFollowModel().getMaxDecel()));
1968 #ifdef DEBUG_SLOW_DOWN 1972 <<
" slowing down for" 1994 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2010 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2022 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2028 <<
" potential=" << potential
2041 #ifdef DEBUG_WANTS_CHANGE 2043 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
2049 if (leader.first != 0) {
2051 v =
MIN2(v, stopSpeed);
2052 #ifdef DEBUG_WANTS_CHANGE 2054 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
2075 return MAX2(-speedBound,
MIN2(speedBound,
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...
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)
static MSPModel * getModel()
#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
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...
static double _2double(const E *const data)
converts a char-type array into the double value described by it
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.
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.
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)
#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.
#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...