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 64 #define OPPOSITE_URGENCY (double)5.0 66 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 67 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 68 #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) 70 #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 71 #define ROUNDABOUT_DIST_TRESH (double)10.0 // roundabout distances below ROUNDABOUT_DIST_TRESH are not multiplied by ROUNDABOUT_DIST_FACTOR 73 #define KEEP_RIGHT_HEADWAY (double)2.0 74 #define MAX_ONRAMP_LENGTH (double)200. 75 #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 77 #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 78 #define LC_ASSUMED_DECEL (double)1.0 // the minimal constant deceleration assumed to estimate the duration of a continuous lane-change at its initiation. 80 #define REACT_TO_STOPPED_DISTANCE 100 95 #define DEBUG_COND (myVehicle.isSelected()) 103 mySpeedGainProbability(0),
104 myKeepRightProbability(0),
105 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.;
239 #ifdef DEBUG_PATCH_SPEED 250 #ifdef DEBUG_PATCH_SPEED 252 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
255 return MAX2(min, safe);
260 double nVSafe = wanted;
275 #ifdef DEBUG_PATCH_SPEED 282 #ifdef DEBUG_PATCH_SPEED 284 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
288 #ifdef DEBUG_PATCH_SPEED 290 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
298 #ifdef DEBUG_PATCH_SPEED 311 #ifdef DEBUG_PATCH_SPEED 316 return (max + wanted) / (double) 2.0;
320 #ifdef DEBUG_PATCH_SPEED 326 return (
MAX2(0., min) + wanted) / (double) 2.0;
332 #ifdef DEBUG_PATCH_SPEED 337 return (max + wanted) / (double) 2.0;
378 #ifdef DEBUG_PATCH_SPEED 383 return (max + wanted) / (double) 2.0;
387 #ifdef DEBUG_PATCH_SPEED 415 #ifdef DEBUG_INFORMED 419 <<
" informedBy=" << sender->
getID()
420 <<
" info=" << pinfo->second
421 <<
" vSafe=" << pinfo->first
433 double overtakeDist = (gap
438 return MAX2(overtakeDist, 0.);
446 const std::pair<MSVehicle*, double>& neighLead,
447 double remainingSeconds) {
456 #ifdef DEBUG_INFORMER 458 std::cout <<
"\nINFORM_LEADER" 463 const MSVehicle*
const nv = neighLead.first;
471 neighNextGap = neighLead.second +
SPEED2DIST(neighNextSpeed - plannedSpeed);
476 #ifdef DEBUG_INFORMER 478 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 485 const double dv = plannedSpeed - nv->
getSpeed();
488 overtakeTime = overtakeDist / dv;
491 overtakeTime = remainingSeconds + 1;
494 #ifdef DEBUG_INFORMER 497 <<
"\nnv = " << nv->
getID()
498 <<
"\nplannedSpeed = " << plannedSpeed
499 <<
"\nleaderSpeed = " << nv->
getSpeed()
501 <<
"\nremainingSeconds = " << remainingSeconds
502 <<
"\novertakeDist = " << overtakeDist
503 <<
"\novertakeTime = " << overtakeTime
518 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
523 const double targetSpeed =
MAX2(
532 #ifdef DEBUG_INFORMER 535 <<
" cannot overtake leader nv=" << nv->
getID()
539 <<
" overtakeDist=" << overtakeDist
540 <<
" overtakeTime=" << overtakeTime
541 <<
" remainingSeconds=" << remainingSeconds
542 <<
" currentGap=" << neighLead.second
544 <<
" neighNextSpeed=" << neighNextSpeed
545 <<
" neighNextGap=" << neighNextGap
546 <<
" targetSpeed=" << targetSpeed
547 <<
" nextSpeed=" << nextSpeed
555 #ifdef DEBUG_INFORMER 558 <<
" cannot overtake fast leader nv=" << nv->
getID()
562 <<
" overtakeDist=" << overtakeDist
564 <<
" overtakeTime=" << overtakeTime
565 <<
" remainingSeconds=" << remainingSeconds
566 <<
" currentGap=" << neighLead.second
567 <<
" targetSpeed=" << targetSpeed
576 #ifdef DEBUG_INFORMER 579 <<
" wants to overtake leader nv=" << nv->
getID()
581 <<
" overtakeDist=" << overtakeDist
582 <<
" remainingSeconds=" << remainingSeconds
583 <<
" overtakeTime=" << overtakeTime
584 <<
" currentGap=" << neighLead.second
594 const double targetSpeed =
MAX2(
598 #ifdef DEBUG_INFORMER 600 std::cout <<
" not blocked by leader nv=" << nv->
getID()
602 <<
" gap=" << neighLead.second
603 <<
" neighNextSpeed=" << neighNextSpeed
604 <<
" neighNextGap=" << neighNextGap
606 <<
" targetSpeed=" << targetSpeed
610 return MIN2(targetSpeed, plannedSpeed);
618 const std::pair<MSVehicle*, double>& neighFollow,
619 double remainingSeconds,
620 double plannedSpeed) {
625 #ifdef DEBUG_INFORMER 627 std::cout <<
"\nINFORM_FOLLOWER" 633 #ifdef DEBUG_INFORMER 635 std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 643 if ((neededGap - neighFollow.second) / remainingSeconds < (
MAX2(plannedSpeed, 0.) - nv->
getSpeed())) {
644 #ifdef DEBUG_INFORMER 646 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help." <<
"\nneededGap = " << neededGap <<
"\n";
666 double neighNewSpeed;
668 double neighNewSpeed1s;
678 dv = plannedSpeed - neighNewSpeed1s;
685 decelGap = neighFollow.second + dv;
692 neighNewSpeed1s = nv->
getSpeed() - helpDecel;
704 #ifdef DEBUG_INFORMER 708 <<
" plannedSpeed=" << plannedSpeed
709 <<
" threshold=" << onRampThreshold
710 <<
" neighNewSpeed=" << neighNewSpeed
711 <<
" neighNewSpeed1s=" << neighNewSpeed1s
713 <<
" gap=" << neighFollow.second
714 <<
" decelGap=" << decelGap
715 <<
" secureGap=" << secureGap
722 && neighNewSpeed1s < onRampThreshold) {
726 if (decelGap > 0 && decelGap >= secureGap) {
734 double vsafe, vsafe1;
743 assert(vsafe <= vsafe1);
754 #ifdef DEBUG_INFORMER 756 std::cout <<
"nextGap=" << nextGap <<
" (without help decel) \n";
764 MAX2(0., plannedSpeed),
772 nv->
getSpeed(), plannedAccel, -decel2,
782 MAX2(0., plannedSpeed),
787 #ifdef DEBUG_INFORMER 789 std::cout <<
"nextGap=" << nextGap
790 <<
" (with vsafe1 and help decel) \nvsafe1=" << vsafe1
791 <<
" vsafe=" << vsafe
800 if (nextGap < nextSecureGap) {
802 vsafe = neighNewSpeed;
805 #ifdef DEBUG_INFORMER 807 std::cout <<
"nextGap=" << nextGap
808 <<
" minNextSecureGap=" << nextSecureGap
809 <<
" vsafe=" << vsafe <<
"\n";
817 #ifdef DEBUG_INFORMER 819 std::cout <<
" wants to cut in before nv=" << nv->
getID()
820 <<
" vsafe1=" << vsafe1 <<
" vsafe=" << vsafe
846 #ifdef DEBUG_INFORMER 848 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
855 #ifdef DEBUG_INFORMER 857 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
876 #ifdef DEBUG_INFORMER 880 std::cout <<
" wants right follower to slow down a bit\n";
887 #ifdef DEBUG_INFORMER 890 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
912 if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) {
913 #ifdef DEBUG_INFORMER 915 std::cout <<
" wants to cut in before follower nv=" << nv->
getID() <<
" (eventually)\n";
928 #ifdef DEBUG_INFORMER 932 <<
" informs follower " << nv->
getID()
933 <<
" vhelp=" << vhelp
942 const double needDV = overtakeDist / remainingSeconds;
946 #ifdef DEBUG_INFORMER 950 <<
" wants to be overtaken by=" << nv->
getID()
951 <<
" overtakeDist=" << overtakeDist
953 <<
" vhelp=" << vhelp
954 <<
" needDV=" << needDV
963 double vsafe, vsafe1;
977 double anticipationTime = 1.;
988 if (anticipatedGap > secureGap) {
995 if (anticipatedGap < secureGap) {
1006 #ifdef DEBUG_INFORMER 1008 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
1052 const std::pair<MSVehicle*, double>& leader,
1053 const std::pair<MSVehicle*, double>& neighLead,
1054 const std::pair<MSVehicle*, double>& neighFollow,
1056 const std::vector<MSVehicle::LaneQ>& preb,
1059 assert(laneOffset == 1 || laneOffset == -1);
1063 int bestLaneOffset = 0;
1068 double currentDist = 0;
1069 double neighDist = 0;
1078 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1079 for (
int p = 0; p < (int) preb.size(); ++p) {
1080 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1081 assert(p + prebOffset < (
int)preb.size());
1083 neigh = preb[p + prebOffset];
1084 currentDist = curr.
length;
1085 neighDist = neigh.
length;
1086 bestLaneOffset = curr.bestLaneOffset;
1087 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1088 #ifdef DEBUG_WANTS_CHANGE 1092 <<
" bestLaneOffsetOld=" << bestLaneOffset
1093 <<
" bestLaneOffsetNew=" << laneOffset
1097 bestLaneOffset = prebOffset;
1099 best = preb[p + bestLaneOffset];
1105 const bool right = (laneOffset == -1);
1107 neigh = preb[preb.size() - 1];
1110 bestLaneOffset = -1;
1112 neighDist = neigh.
length;
1113 currentDist = curr.
length;
1119 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1125 if (lastBlocked != firstBlocked) {
1129 #ifdef DEBUG_WANTS_CHANGE 1138 <<
" leaderGap=" << leader.second
1140 <<
" neighLeadGap=" << neighLead.second
1142 <<
" neighFollowGap=" << neighFollow.second
1165 assert(memoryFactor > 0.);
1173 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped() && leader.second < (currentDist - posOnLane)) {
1178 + leader.first->getVehicleType().getLengthWithGap()
1180 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped() && neighLead.second < (currentDist - posOnLane)) {
1183 + neighLead.first->getVehicleType().getLengthWithGap()
1184 + neighLead.second);
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 int remainingLanes =
MAX2(1, abs(bestLaneOffset));
1393 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1397 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1402 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1405 #ifdef DEBUG_WANTS_CHANGE 1410 <<
" remainingSeconds=" << remainingSeconds
1411 <<
" plannedSpeed=" << plannedSpeed
1419 const double inconvenience =
MIN2((
double)1.0, (laneOffset < 0
1426 if (roundaboutEdgesAhead > 1) {
1428 #ifdef DEBUG_WANTS_CHANGE 1432 <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead
1462 #ifdef DEBUG_WANTS_CHANGE 1464 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1484 && (!speedGainInconvenient)
1486 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1489 #ifdef DEBUG_COOPERATE 1493 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1495 << (((
myOwnState & myLca) == 0) ?
" (counter)" :
"")
1524 const bool acceleratingLeader = (neighLead.first != 0 && neighLead.first->getAcceleration() > 0)
1525 || (leader.first != 0 && leader.first->getAcceleration() > 0);
1527 if (acceleratingLeader) {
1534 if (neighLead.first == 0) {
1538 &
myVehicle, correctedSpeed, neighLead.second, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1540 if (leader.first == 0) {
1544 &
myVehicle, correctedSpeed, leader.second, leader.first->
getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1547 if (neighLead.first == 0) {
1551 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel(),
true));
1553 if (leader.first == 0) {
1557 leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel(),
true));
1567 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1570 #ifdef DEBUG_WANTS_CHANGE 1574 <<
" currentDist=" << currentDist
1575 <<
" neighDist=" << neighDist
1576 <<
" thisVSafe=" << thisLaneVSafe
1577 <<
" neighVSafe=" << neighLaneVSafe
1578 <<
" relGain=" <<
toString(relativeGain, 8)
1585 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1602 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1611 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1612 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1613 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1615 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1616 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1619 if (checkOverTakeRight && leader.first != 0
1620 && leader.first->getLane()->getVehicleMaxSpeed(leader.first) < vMax) {
1621 fullSpeedGap =
MIN2(fullSpeedGap, leader.second);
1622 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - leader.first->getSpeed()));
1623 const double relativeGain = (vMax - leader.first->getLane()->getVehicleMaxSpeed(leader.first)) /
MAX2(vMax,
1632 #ifdef DEBUG_WANTS_CHANGE 1637 <<
" neighDist=" << neighDist
1639 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1641 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1642 <<
" acceptanceTime=" << acceptanceTime
1643 <<
" fullSpeedGap=" << fullSpeedGap
1644 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1645 <<
" dProb=" << deltaProb
1658 #ifdef DEBUG_WANTS_CHANGE 1664 <<
" thisLaneVSafe=" << thisLaneVSafe
1665 <<
" neighLaneVSafe=" << neighLaneVSafe
1666 <<
" relativeGain=" << relativeGain
1667 <<
" blocked=" << blocked
1681 if (thisLaneVSafe > neighLaneVSafe) {
1686 }
else if (thisLaneVSafe == neighLaneVSafe) {
1704 #ifdef DEBUG_WANTS_CHANGE 1710 <<
" thisLaneVSafe=" << thisLaneVSafe
1711 <<
" neighLaneVSafe=" << neighLaneVSafe
1712 <<
" relativeGain=" << relativeGain
1713 <<
" blocked=" << blocked
1719 && (relativeGain >
NUMERICAL_EPS || changeLeftToAvoidOvertakeRight)
1729 && relativeGain >= 0
1730 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1737 #ifdef DEBUG_WANTS_CHANGE 1743 <<
" thisLaneVSafe=" << thisLaneVSafe
1744 <<
" neighLaneVSafe=" << neighLaneVSafe
1755 double& roundaboutDistanceAhead,
double& roundaboutDistanceAheadNeigh,
int& roundaboutEdgesAhead,
int& roundaboutEdgesAheadNeigh) {
1767 roundaboutDistanceAheadNeigh = 0;
1768 double neighPosition = pos;
1778 if (*i != 0 && *i != veh.
getLane()) {
1783 assert(nextLane != 0);
1792 #ifdef DEBUG_WANTS_CHANGE 1794 std::cout <<
"roundaboutDistanceAhead = " << roundaboutDistanceAhead
1795 <<
" roundaboutDistanceAheadNeigh = " << roundaboutDistanceAheadNeigh
1802 roundaboutEdgesAhead = 0;
1804 const MSLane* lane = *it;
1806 roundaboutEdgesAhead += 1;
1807 }
else if (roundaboutEdgesAhead > 0) {
1812 roundaboutEdgesAheadNeigh = 0;
1814 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
1815 roundaboutEdgesAheadNeigh += 1;
1816 }
else if (roundaboutEdgesAheadNeigh > 0) {
1833 if (roundaboutEdgesAhead > 1) {
1856 for (std::vector<MSLane*>::const_iterator i = continuationLanes.begin(); i != continuationLanes.end(); i++) {
1857 assert((*i) == 0 || !(*i)->getEdge().isInternal());
1861 bool encounteredRoundabout =
false;
1862 double roundaboutDistanceAhead = 0.;
1865 std::vector<MSLane*>::const_iterator j = continuationLanes.begin();
1866 while (j != continuationLanes.end() && *j == 0) {
1871 if (j == continuationLanes.end()) {
1873 assert(initialLane == 0);
1875 }
else if (initialLane == 0) {
1880 }
else if (!initialLane->
isInternal() && initialLane != *j) {
1887 assert(position >= 0. && position <= initialLane->getLength());
1889 assert(initialLane == *j);
1890 roundaboutDistanceAhead += initialLane->
getLength() - position;
1891 if (j + 1 == continuationLanes.end() || *(j + 1) == 0 || !(*(j + 1))->getEdge().isRoundabout()) {
1895 const MSLane* nextLane = *(j + 1);
1903 roundaboutDistanceAhead += initialLane->
getLength() - position;
1905 roundaboutDistanceAhead += initialLane->
getLinkCont()[0]->getInternalLengthsAfter();
1910 for (std::vector<MSLane*>::const_iterator it = j; it != continuationLanes.end(); ++it) {
1911 const MSLane* lane = *it;
1914 encounteredRoundabout =
true;
1916 roundaboutDistanceAhead += lane->
getLength();
1921 if (it + 1 != continuationLanes.end() && *(it + 1) != 0 && (*(it + 1))->getEdge().isRoundabout()) {
1926 roundaboutDistanceAhead += linkLength;
1928 }
else if (encounteredRoundabout) {
1933 return roundaboutDistanceAhead;
1941 if ((*blocked) != 0) {
1943 #ifdef DEBUG_SLOW_DOWN 1967 (*blocked)->getCarFollowModel().getMaxDecel()));
1970 #ifdef DEBUG_SLOW_DOWN 1974 <<
" slowing down for" 1996 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2012 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2024 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 2030 <<
" potential=" << potential
2043 #ifdef DEBUG_WANTS_CHANGE 2045 std::cout <<
SIMTIME <<
" adapt to pedestrians on lane=" << lane->
getID() <<
"\n";
2051 if (leader.first != 0) {
2053 v =
MIN2(v, stopSpeed);
2054 #ifdef DEBUG_WANTS_CHANGE 2056 std::cout <<
SIMTIME <<
" pedLeader=" << leader.first->getID() <<
" dist=" << leader.second <<
" v=" << v <<
"\n";
2077 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...
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...
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)
virtual 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)
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.
#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...