50 #define LOOK_FORWARD (double)10. 52 #define JAM_FACTOR (double)1. 54 #define LCA_RIGHT_IMPATIENCE (double)-1. 55 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27. 57 #define LOOK_AHEAD_MIN_SPEED 0.0 58 #define LOOK_AHEAD_SPEED_MEMORY 0.9 60 #define HELP_DECEL_FACTOR (double)1.0 62 #define HELP_OVERTAKE (double)(10.0 / 3.6) 63 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 66 #define OVERTAKE_RIGHT_THRESHOLD (double)(5/3.6) 68 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 69 #define URGENCY (double)2.0 71 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 72 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 73 #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) 75 #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 76 #define ROUNDABOUT_DIST_TRESH (double)10.0 // roundabout distances below ROUNDABOUT_DIST_TRESH are not multiplied by ROUNDABOUT_DIST_FACTOR 78 #define KEEP_RIGHT_HEADWAY (double)2.0 79 #define MAX_ONRAMP_LENGTH (double)200. 80 #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 94 #define DEBUG_COND (myVehicle.isSelected()) 102 mySpeedGainProbability(0),
103 myKeepRightProbability(0),
104 myLeadingBlockerLength(0),
115 #ifdef DEBUG_CONSTRUCTOR 151 const std::pair<MSVehicle*, double>& leader,
152 const std::pair<MSVehicle*, double>& neighLead,
153 const std::pair<MSVehicle*, double>& neighFollow,
155 const std::vector<MSVehicle::LaneQ>& preb,
159 #ifdef DEBUG_WANTS_CHANGE 161 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 168 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
173 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
175 #ifdef DEBUG_WANTS_CHANGE 188 #ifdef DEBUG_PATCH_SPEED 190 std::cout <<
"\nPATCH_SPEED\n" 197 <<
" wanted=" << wanted
204 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
206 #ifdef DEBUG_PATCH_SPEED 208 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
221 #ifdef DEBUG_PATCH_SPEED 227 <<
" wanted=" << wanted << std::endl;
232 double MAGIC_offset = 1.;
236 #ifdef DEBUG_PATCH_SPEED 247 #ifdef DEBUG_PATCH_SPEED 249 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
252 return MAX2(min, safe);
257 double nVSafe = wanted;
272 #ifdef DEBUG_PATCH_SPEED 279 #ifdef DEBUG_PATCH_SPEED 281 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
285 #ifdef DEBUG_PATCH_SPEED 287 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
295 #ifdef DEBUG_PATCH_SPEED 308 #ifdef DEBUG_PATCH_SPEED 313 return (max + wanted) / (double) 2.0;
317 #ifdef DEBUG_PATCH_SPEED 323 return (
MAX2(0., min) + wanted) / (double) 2.0;
329 #ifdef DEBUG_PATCH_SPEED 334 return (max + wanted) / (double) 2.0;
375 #ifdef DEBUG_PATCH_SPEED 380 return (max + wanted) / (double) 2.0;
384 #ifdef DEBUG_PATCH_SPEED 412 #ifdef DEBUG_INFORMED 416 <<
" informedBy=" << sender->
getID()
417 <<
" info=" << pinfo->second
418 <<
" vSafe=" << pinfo->first
430 double overtakeDist = (gap
435 return MAX2(overtakeDist, 0.);
443 const std::pair<MSVehicle*, double>& neighLead,
444 double remainingSeconds) {
453 #ifdef DEBUG_INFORMER 455 std::cout <<
"\nINFORM_LEADER" 461 assert(neighLead.first != 0);
463 #ifdef DEBUG_INFORMER 465 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 472 const double dv = plannedSpeed - nv->
getSpeed();
475 overtakeTime = overtakeDist / dv;
478 overtakeTime = remainingSeconds + 1;
481 #ifdef DEBUG_INFORMER 484 <<
"\nnv = " << nv->
getID()
485 <<
"\nplannedSpeed = " << plannedSpeed
486 <<
"\nleaderSpeed = " << nv->
getSpeed()
488 <<
"\nremainingSeconds = " << remainingSeconds
489 <<
"\novertakeDist = " << overtakeDist
490 <<
"\novertakeTime = " << overtakeTime
505 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
517 #ifdef DEBUG_INFORMER 520 <<
" cannot overtake leader nv=" << nv->
getID()
524 <<
" overtakeDist=" << overtakeDist
525 <<
" overtakeTime=" << overtakeTime
526 <<
" remainingSeconds=" << remainingSeconds
527 <<
" currentGap=" << neighLead.second
530 <<
" targetSpeed=" << targetSpeed
531 <<
" nextSpeed=" << nextSpeed
539 #ifdef DEBUG_INFORMER 542 <<
" cannot overtake fast leader nv=" << nv->
getID()
546 <<
" overtakeDist=" << overtakeDist
548 <<
" overtakeTime=" << overtakeTime
549 <<
" remainingSeconds=" << remainingSeconds
550 <<
" currentGap=" << neighLead.second
551 <<
" targetSpeed=" << targetSpeed
560 #ifdef DEBUG_INFORMER 563 <<
" wants to overtake leader nv=" << nv->
getID()
565 <<
" overtakeDist=" << overtakeDist
566 <<
" remainingSeconds=" << remainingSeconds
567 <<
" overtakeTime=" << overtakeTime
568 <<
" currentGap=" << neighLead.second
576 }
else if (neighLead.first != 0) {
579 double dv, nextNVSpeed;
597 #ifdef DEBUG_INFORMER 599 std::cout <<
" not blocked by leader nv=" << nv->
getID()
601 <<
" gap=" << neighLead.second
602 <<
" nextGap=" << neighLead.second - dv
604 <<
" targetSpeed=" << targetSpeed
608 return MIN2(targetSpeed, plannedSpeed);
619 const std::pair<MSVehicle*, double>& neighFollow,
620 double remainingSeconds,
621 double plannedSpeed) {
626 #ifdef DEBUG_INFORMER 628 std::cout <<
"\nINFORM_FOLLOWER" 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;
1071 double currentDist = 0;
1072 double neighDist = 0;
1081 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1082 for (
int p = 0; p < (int) preb.size(); ++p) {
1083 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1084 assert(p + prebOffset < (
int)preb.size());
1086 neigh = preb[p + prebOffset];
1087 currentDist = curr.
length;
1088 neighDist = neigh.
length;
1089 bestLaneOffset = curr.bestLaneOffset;
1090 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1091 #ifdef DEBUG_WANTS_CHANGE 1095 <<
" bestLaneOffsetOld=" << bestLaneOffset
1096 <<
" bestLaneOffsetNew=" << laneOffset
1100 bestLaneOffset = prebOffset;
1102 best = preb[p + bestLaneOffset];
1108 const bool right = (laneOffset == -1);
1110 neigh = preb[preb.size() - 1];
1113 bestLaneOffset = -1;
1115 neighDist = neigh.
length;
1116 currentDist = curr.
length;
1122 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1128 if (lastBlocked != firstBlocked) {
1132 #ifdef DEBUG_WANTS_CHANGE 1141 <<
" leaderGap=" << leader.second
1143 <<
" neighLeadGap=" << neighLead.second
1145 <<
" neighFollowGap=" << neighFollow.second
1168 assert(memoryFactor > 0.);
1176 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped()) {
1181 + leader.first->getVehicleType().getLengthWithGap());
1182 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped()) {
1185 + neighLead.first->getVehicleType().getLengthWithGap();
1201 double roundaboutDistanceAhead = 0;
1202 double roundaboutDistanceAheadNeigh = 0;
1203 int roundaboutEdgesAhead = 0;
1204 int roundaboutEdgesAheadNeigh = 0;
1206 getRoundaboutAheadInfo(
this, curr, neigh, roundaboutDistanceAhead, roundaboutDistanceAheadNeigh, roundaboutEdgesAhead, roundaboutEdgesAheadNeigh);
1210 neighDist +=
roundaboutDistBonus(roundaboutDistanceAheadNeigh, roundaboutEdgesAheadNeigh);
1212 #ifdef DEBUG_WANTS_CHANGE 1214 if (roundaboutEdgesAhead > 0) {
1215 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1223 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1224 const double neighLeftPlace =
MAX2((
double) 0, neighDist - posOnLane - maxJam);
1227 double thisLaneVSafe = vMax;
1232 #ifdef DEBUG_WANTS_CHANGE 1237 <<
" laDist=" << laDist
1238 <<
" currentDist=" << currentDist
1239 <<
" usableDist=" << usableDist
1240 <<
" bestLaneOffset=" << bestLaneOffset
1242 <<
" best.length=" << best.
length 1243 <<
" maxJam=" << maxJam
1244 <<
" neighLeftPlace=" << neighLeftPlace
1249 bool changeLeftToAvoidOvertakeRight =
false;
1256 if (neighLead.first != 0 && checkOverTakeRight && !right) {
1263 double vSafe =
MAX2(
1270 thisLaneVSafe =
MIN2(thisLaneVSafe, vSafe);
1273 const double deltaGapFuture = deltaV * 8;
1276 if (vSafeFuture < vSafe) {
1277 const double relativeGain = deltaV /
MAX2(vMax,
1280 changeLeftToAvoidOvertakeRight =
true;
1282 #ifdef DEBUG_WANTS_CHANGE 1285 <<
" avoid overtaking on the right nv=" << nv->
getID()
1286 <<
" deltaV=" << deltaV
1296 if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
1303 #ifdef DEBUG_WANTS_CHANGE 1305 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1309 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1314 #ifdef DEBUG_WANTS_CHANGE 1316 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1320 }
else if (bestLaneOffset == 0
1321 && (leader.first == 0 || !leader.first->isStopped())
1323 && roundaboutEdgesAhead == 0
1329 #ifdef DEBUG_WANTS_CHANGE 1331 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1338 #ifdef DEBUG_WANTS_CHANGE 1344 if ((ret & lcaCounter) != 0) {
1348 #ifdef DEBUG_WANTS_CHANGE 1350 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
1361 if (changeToBest && abs(bestLaneOffset) > 1) {
1364 #ifdef DEBUG_WANTS_CHANGE 1366 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1374 if (*firstBlocked != neighLead.first) {
1378 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1382 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1387 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1390 #ifdef DEBUG_WANTS_CHANGE 1395 <<
" remainingSeconds=" << remainingSeconds
1396 <<
" plannedSpeed=" << plannedSpeed
1404 const double inconvenience =
MIN2((
double)1.0, (laneOffset < 0
1411 if (roundaboutEdgesAhead > 1) {
1413 #ifdef DEBUG_WANTS_CHANGE 1417 <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead
1447 #ifdef DEBUG_WANTS_CHANGE 1449 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1469 && (!speedGainInconvenient)
1471 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1474 #ifdef DEBUG_WANTS_CHANGE 1478 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1509 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1510 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1512 if (acceleratingLeader) {
1519 if (neighLead.first == 0) {
1523 &
myVehicle, correctedSpeed, neighLead.second, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1525 if (leader.first == 0) {
1529 &
myVehicle, correctedSpeed, leader.second, leader.first->
getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1532 if (neighLead.first == 0) {
1536 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel(),
true));
1538 if (leader.first == 0) {
1542 leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel(),
true));
1552 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1555 #ifdef DEBUG_WANTS_CHANGE 1559 <<
" currentDist=" << currentDist
1560 <<
" neighDist=" << neighDist
1561 <<
" thisVSafe=" << thisLaneVSafe
1562 <<
" neighVSafe=" << neighLaneVSafe
1563 <<
" relGain=" <<
toString(relativeGain, 8)
1570 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1587 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1596 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1597 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1598 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1600 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1601 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1604 if (checkOverTakeRight && leader.first != 0
1605 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1606 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1607 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1608 const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1617 #ifdef DEBUG_WANTS_CHANGE 1622 <<
" neighDist=" << neighDist
1624 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1626 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1627 <<
" acceptanceTime=" << acceptanceTime
1628 <<
" fullSpeedGap=" << fullSpeedGap
1629 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1630 <<
" dProb=" << deltaProb
1643 #ifdef DEBUG_WANTS_CHANGE 1649 <<
" thisLaneVSafe=" << thisLaneVSafe
1650 <<
" neighLaneVSafe=" << neighLaneVSafe
1651 <<
" relativeGain=" << relativeGain
1652 <<
" blocked=" << blocked
1666 if (thisLaneVSafe > neighLaneVSafe) {
1671 }
else if (thisLaneVSafe == neighLaneVSafe) {
1689 #ifdef DEBUG_WANTS_CHANGE 1695 <<
" thisLaneVSafe=" << thisLaneVSafe
1696 <<
" neighLaneVSafe=" << neighLaneVSafe
1697 <<
" relativeGain=" << relativeGain
1698 <<
" blocked=" << blocked
1704 && (relativeGain >
NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1714 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1721 #ifdef DEBUG_WANTS_CHANGE 1727 <<
" thisLaneVSafe=" << thisLaneVSafe
1728 <<
" neighLaneVSafe=" << neighLaneVSafe
1739 double& roundaboutDistanceAhead,
double& roundaboutDistanceAheadNeigh,
int& roundaboutEdgesAhead,
int& roundaboutEdgesAheadNeigh) {
1751 roundaboutDistanceAheadNeigh = 0;
1752 double neighPosition = pos;
1762 if (*i != 0 && *i != veh.
getLane()) {
1767 assert(nextLane != 0);
1776 #ifdef DEBUG_WANTS_CHANGE 1778 std::cout <<
"roundaboutDistanceAhead = " << roundaboutDistanceAhead
1779 <<
" roundaboutDistanceAheadNeigh = " << roundaboutDistanceAheadNeigh
1786 roundaboutEdgesAhead = 0;
1788 const MSLane* lane = *it;
1790 roundaboutEdgesAhead += 1;
1791 }
else if (roundaboutEdgesAhead > 0) {
1796 roundaboutEdgesAheadNeigh = 0;
1798 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
1799 roundaboutEdgesAheadNeigh += 1;
1800 }
else if (roundaboutEdgesAheadNeigh > 0) {
1817 if (roundaboutEdgesAhead > 1) {
1840 for (std::vector<MSLane*>::const_iterator i = continuationLanes.begin(); i != continuationLanes.end(); i++) {
1841 assert((*i) == 0 || !(*i)->getEdge().isInternal());
1845 bool encounteredRoundabout =
false;
1846 double roundaboutDistanceAhead = 0.;
1849 std::vector<MSLane*>::const_iterator j = continuationLanes.begin();
1850 while (j != continuationLanes.end() && *j == 0) {
1855 if (j == continuationLanes.end()) {
1857 assert(initialLane == 0);
1859 }
else if (initialLane == 0) {
1864 }
else if (!initialLane->
isInternal() && initialLane != *j) {
1871 assert(position >= 0. && position <= initialLane->getLength());
1873 assert(initialLane == *j);
1874 roundaboutDistanceAhead += initialLane->
getLength() - position;
1875 if (j + 1 == continuationLanes.end() || *(j + 1) == 0 || !(*(j + 1))->getEdge().isRoundabout()) {
1879 const MSLane* nextLane = *(j + 1);
1887 roundaboutDistanceAhead += initialLane->
getLength() - position;
1889 roundaboutDistanceAhead += initialLane->
getLinkCont()[0]->getInternalLengthsAfter();
1894 for (std::vector<MSLane*>::const_iterator it = j; it != continuationLanes.end(); ++it) {
1895 const MSLane* lane = *it;
1898 encounteredRoundabout =
true;
1900 roundaboutDistanceAhead += lane->
getLength();
1905 if (it + 1 != continuationLanes.end() && *(it + 1) != 0 && (*(it + 1))->getEdge().isRoundabout()) {
1910 roundaboutDistanceAhead += linkLength;
1912 }
else if (encounteredRoundabout) {
1917 return roundaboutDistanceAhead;
1925 if ((*blocked) != 0) {
1927 #ifdef DEBUG_SLOW_DOWN 1951 (*blocked)->getCarFollowModel().getMaxDecel()));
1954 #ifdef DEBUG_SLOW_DOWN 1958 <<
" slowing down for" 1980 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1996 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2008 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2014 <<
" potential=" << potential
2027 #ifdef DEBUG_WANTS_CHANGE 2029 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
2035 if (leader.first != 0) {
2037 v =
MIN2(v, stopSpeed);
2038 #ifdef DEBUG_WANTS_CHANGE 2040 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
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 ...
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.
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 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
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const =0
Computes the vehicle's follow speed (no dawdling)
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 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 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...
bool cancelRequest(int state)
whether the influencer cancels the given request
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)
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
#define LOOK_AHEAD_SPEED_MEMORY
const double myExperimentalParam1
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()...
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
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
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
public emergency vehicles
void * inform(void *info, MSVehicle *sender)
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...