37 #define MAGIC_OFFSET 1. 38 #define LOOK_FORWARD (double)10. 40 #define JAM_FACTOR (double)1. 43 #define LCA_RIGHT_IMPATIENCE (double)-1. 44 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27. 45 #define MAX_ONRAMP_LENGTH (double)200. 47 #define LOOK_AHEAD_MIN_SPEED 0.0 48 #define LOOK_AHEAD_SPEED_MEMORY 0.9 50 #define HELP_DECEL_FACTOR (double)1.0 52 #define HELP_OVERTAKE (double)(10.0 / 3.6) 53 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 55 #define KEEP_RIGHT_HEADWAY (double)2.0 57 #define URGENCY (double)2.0 59 #define ROUNDABOUT_DIST_BONUS (double)100.0 61 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 62 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 64 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 66 #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 67 #define GAIN_PERCEPTION_THRESHOLD 0.05 // the minimum relative speed gain which affects the behavior 69 #define SPEED_GAIN_MIN_SECONDS 20.0 71 #define ARRIVALPOS_LAT_THRESHOLD 100.0 74 #define LATGAP_SPEED_THRESHOLD (50 / 3.6) 77 #define LATGAP_SPEED_THRESHOLD2 (50 / 3.6) 80 #define SPEEDGAIN_DECAY_FACTOR 0.5 82 #define SPEEDGAIN_MEMORY_FACTOR 0.5 107 #define DEBUG_COND (myVehicle.isSelected()) 119 mySpeedGainProbabilityRight(0),
120 mySpeedGainProbabilityLeft(0),
121 myKeepRightProbability(0),
122 myLeadingBlockerLength(0),
126 myCanChangeFully(true),
127 mySafeLatDistRight(0),
128 mySafeLatDistLeft(0),
137 v.getVehicleType().getMinGapLat()) /
138 v.getVehicleType().getMinGapLat()))),
141 myMinImpatience(myImpatience),
180 const std::vector<MSVehicle::LaneQ>& preb,
183 double& latDist,
double& maneuverDist,
int& blocked) {
186 const std::string changeType = laneOffset == -1 ?
"right" : (laneOffset == 1 ?
"left" :
"current");
188 #ifdef DEBUG_MANEUVER 197 <<
" considerChangeTo=" << changeType
204 leaders, followers, blockers,
205 neighLeaders, neighFollowers, neighBlockers,
207 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
209 result =
keepLatGap(result, leaders, followers, blockers,
210 neighLeaders, neighFollowers, neighBlockers,
211 neighLane, laneOffset, latDist, maneuverDist, blocked);
213 result |=
getLCA(result, latDist);
215 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE) 216 double latDistTmp = latDist;
219 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE) 221 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" maneuverDist=" << maneuverDist <<
" latDist=" << latDistTmp <<
" mySpeedPrev=" <<
mySpeedLat <<
" speedLat=" <<
DIST2SPEED(latDist) <<
" latDist2=" << latDist <<
"\n";
228 <<
" wantsChangeTo=" << changeType
229 <<
" latDist=" << latDist
230 <<
" maneuverDist=" << maneuverDist
238 <<
" wantsNoChangeTo=" << changeType
296 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
297 #ifdef DEBUG_PATCHSPEED 299 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
306 <<
" wanted=" << wanted
329 #ifdef DEBUG_PATCHSPEED 339 #ifdef DEBUG_PATCHSPEED 341 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
344 return MAX2(min, safe);
348 double nVSafe = wanted;
352 if (v >= min && v <= max) {
353 nVSafe =
MIN2(v, nVSafe);
355 #ifdef DEBUG_PATCHSPEED 357 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" got accel=" << (*i) <<
" nVSafe=" << nVSafe <<
"\n";
361 #ifdef DEBUG_PATCHSPEED 364 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
368 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
376 #ifdef DEBUG_PATCHSPEED 389 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 394 return (max + wanted) / (double) 2.0;
398 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 403 return (min + wanted) / (double) 2.0;
406 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 411 return (max + wanted) / (double) 2.0;
452 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 457 return (max + wanted) / (double) 2.0;
461 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 481 if (pinfo->first >= 0) {
490 <<
" informedBy=" << sender->
getID()
491 <<
" info=" << pinfo->second
492 <<
" vSafe=" << pinfo->first
505 assert(cld.first != 0);
514 double remainingSeconds) {
520 plannedSpeed =
MIN2(plannedSpeed, v);
525 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
532 if (
gDebugFlag2) std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 536 const double dv = plannedSpeed - nv->
getSpeed();
537 const double overtakeDist = (neighLead.second
549 || dv * remainingSeconds < overtakeDist) {
564 <<
" cannot overtake leader nv=" << nv->
getID()
566 <<
" remainingSeconds=" << remainingSeconds
567 <<
" targetSpeed=" << targetSpeed
568 <<
" nextSpeed=" << nextSpeed
579 <<
" cannot overtake fast leader nv=" << nv->
getID()
581 <<
" remainingSeconds=" << remainingSeconds
582 <<
" targetSpeed=" << targetSpeed
593 <<
" wants to overtake leader nv=" << nv->
getID()
595 <<
" remainingSeconds=" << remainingSeconds
596 <<
" currentGap=" << neighLead.second
598 <<
" overtakeDist=" << overtakeDist
608 }
else if (neighLead.first != 0) {
611 double dv, nextNVSpeed;
631 std::cout <<
" not blocked by leader nv=" << nv->
getID()
633 <<
" gap=" << neighLead.second
634 <<
" nextGap=" << neighLead.second - dv
636 <<
" targetSpeed=" << targetSpeed
640 return MIN2(targetSpeed, plannedSpeed);
652 double remainingSeconds,
653 double plannedSpeed) {
657 if (
gDebugFlag2) std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 664 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
667 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
686 const double neighNewSpeed1s =
MAX2(0., nv->
getSpeed() - helpDecel);
687 const double dv = plannedSpeed - neighNewSpeed1s;
689 const double decelGap = neighFollow.second + dv;
695 <<
" egoNV=" << plannedSpeed
696 <<
" nvNewSpeed=" << neighNewSpeed
697 <<
" nvNewSpeed1s=" << neighNewSpeed1s
698 <<
" deltaGap=" << dv
699 <<
" decelGap=" << decelGap
700 <<
" secGap=" << secureGap
704 if (decelGap > 0 && decelGap >= secureGap) {
719 std::cout <<
" wants to cut in before nv=" << nv->
getID()
720 <<
" vsafe1=" << vsafe1
721 <<
" vsafe=" << vsafe
726 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap +
POSITION_EPS)) {
731 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
739 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
755 std::cout <<
" wants right follower to slow down a bit\n";
761 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
770 const double overtakeDist = (neighFollow.second
776 const double needDV = overtakeDist / remainingSeconds;
784 <<
" wants to be overtaken by=" << nv->
getID()
785 <<
" overtakeDist=" << overtakeDist
787 <<
" vhelp=" << vhelp
788 <<
" needDV=" << needDV
794 }
else if (neighFollow.first != 0) {
804 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
812 const std::vector<CLeaderDist>& blockers,
813 double remainingSeconds) {
820 plannedSpeed =
MIN2(plannedSpeed, safe);
823 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
824 plannedSpeed =
MIN2(plannedSpeed,
informLeader(blocked, dir, *it, remainingSeconds));
832 const std::vector<CLeaderDist>& blockers,
833 double remainingSeconds,
834 double plannedSpeed) {
836 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
837 informFollower(blocked, dir, *it, remainingSeconds, plannedSpeed);
865 const double halfWidth =
getWidth() * 0.5;
875 std::vector<double> newExpectedSpeeds;
884 const std::vector<MSLane*>& lanes = currEdge->
getLanes();
885 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
887 for (
int i = 0; i < subLanes; ++i) {
888 newExpectedSpeeds.push_back((*it_lane)->getVehicleMaxSpeed(&
myVehicle));
896 if (subLaneShift < std::numeric_limits<int>::max()) {
898 const int newI = i + subLaneShift;
899 if (newI > 0 && newI < (
int)newExpectedSpeeds.size()) {
917 const std::vector<MSLane*>& lanes = prevEdge->
getLanes();
918 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
919 const MSLane* lane = *it_lane;
920 for (MSLinkCont::const_iterator it_link = lane->
getLinkCont().begin(); it_link != lane->
getLinkCont().end(); ++it_link) {
921 if (&((*it_link)->getLane()->getEdge()) == curEdge) {
923 const MSLane* target = (*it_link)->getLane();
924 const std::vector<MSLane*>& lanes2 = curEdge->
getLanes();
925 for (std::vector<MSLane*>::const_iterator it_lane2 = lanes2.begin(); it_lane2 != lanes2.end(); ++it_lane2) {
926 const MSLane* lane2 = *it_lane2;
927 if (lane2 == target) {
928 return prevShift + curShift;
939 return std::numeric_limits<int>::max();
969 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE) 988 const std::vector<MSVehicle::LaneQ>& preb,
991 double& latDist,
double& maneuverDist,
int& blocked) {
996 int bestLaneOffset = 0;
997 double currentDist = 0;
998 double neighDist = 0;
1005 for (
int p = 0; p < (int) preb.size(); ++p) {
1006 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1007 assert(p + laneOffset < (
int)preb.size());
1009 neigh = preb[p + laneOffset];
1010 currentDist = curr.
length;
1011 neighDist = neigh.
length;
1012 bestLaneOffset = curr.bestLaneOffset;
1014 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
1015 #ifdef DEBUG_WANTSCHANGE 1019 <<
" bestLaneOffsetOld=" << bestLaneOffset
1020 <<
" bestLaneOffsetNew=" << laneOffset
1024 bestLaneOffset = laneOffset;
1030 double driveToNextStop = -std::numeric_limits<double>::max();
1039 #ifdef DEBUG_WANTS_CHANGE 1044 <<
" stopPos=" << stopPos
1045 <<
" currentDist=" << currentDist
1046 <<
" neighDist=" << neighDist
1050 currentDist =
MAX2(currentDist, stopPos);
1051 neighDist =
MAX2(neighDist, stopPos);
1054 const bool right = (laneOffset == -1);
1055 const bool left = (laneOffset == 1);
1058 const bool changeToBest = (right && bestLaneOffset < 0) || (left && bestLaneOffset > 0) || (laneOffset == 0 && bestLaneOffset == 0);
1084 #ifdef DEBUG_WANTSCHANGE 1091 <<
"\n leaders=" << leaders.
toString()
1092 <<
"\n followers=" << followers.
toString()
1093 <<
"\n blockers=" << blockers.
toString()
1094 <<
"\n neighLeaders=" << neighLeaders.
toString()
1095 <<
"\n neighFollowers=" << neighFollowers.
toString()
1096 <<
"\n neighBlockers=" << neighBlockers.
toString()
1097 <<
"\n changeToBest=" << changeToBest
1098 <<
" latLaneDist=" << latLaneDist
1106 if (lastBlocked != firstBlocked) {
1166 int roundaboutEdgesAhead = 0;
1168 if ((*it) !=
nullptr && (*it)->getEdge().isRoundabout()) {
1169 roundaboutEdgesAhead += 1;
1170 }
else if (roundaboutEdgesAhead > 0) {
1175 int roundaboutEdgesAheadNeigh = 0;
1177 if ((*it) !=
nullptr && (*it)->getEdge().isRoundabout()) {
1178 roundaboutEdgesAheadNeigh += 1;
1179 }
else if (roundaboutEdgesAheadNeigh > 0) {
1184 if (roundaboutEdgesAhead > 1) {
1188 if (roundaboutEdgesAhead > 0) {
1189 #ifdef DEBUG_ROUNDABOUTS 1191 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1196 if (laneOffset != 0) {
1208 roundaboutEdgesAhead,
1213 if ((ret &
LCA_STAY) != 0 && latDist == 0) {
1223 if (changeToBest && abs(bestLaneOffset) > 1
1228 #ifdef DEBUG_WANTSCHANGE 1230 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1239 if (*firstBlocked != neighLeadLongest) {
1242 std::vector<CLeaderDist> collectLeadBlockers;
1243 std::vector<CLeaderDist> collectFollowBlockers;
1244 int blockedFully = 0;
1247 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1248 leaders, followers, blockers,
1249 neighLeaders, neighFollowers, neighBlockers, &collectLeadBlockers, &collectFollowBlockers,
1250 false, gapFactor, &blockedFully);
1252 const double absLaneOffset = fabs(bestLaneOffset != 0 ? bestLaneOffset : latDist /
SUMO_const_laneWidth);
1253 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1256 const double plannedSpeed =
informLeaders(blocked, myLca, collectLeadBlockers, remainingSeconds);
1258 if (plannedSpeed >= 0) {
1260 informFollowers(blocked, myLca, collectFollowBlockers, remainingSeconds, plannedSpeed);
1262 if (plannedSpeed > 0) {
1263 commitManoeuvre(blocked, blockedFully, leaders, neighLeaders, neighLane, maneuverDist);
1265 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) 1272 <<
" remainingSeconds=" << remainingSeconds
1273 <<
" plannedSpeed=" << plannedSpeed
1283 if (roundaboutEdgesAhead > 1) {
1292 if ((ret & LCA_STAY) == 0) {
1293 latDist = latLaneDist;
1294 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1295 leaders, followers, blockers,
1296 neighLeaders, neighFollowers, neighBlockers);
1311 const double inconvenience = (latLaneDist < 0
1325 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1328 #ifdef DEBUG_COOPERATE 1335 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1345 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1346 leaders, followers, blockers,
1347 neighLeaders, neighFollowers, neighBlockers);
1371 const double vehWidth =
getWidth();
1373 const double leftVehSide = rightVehSide + vehWidth;
1375 double defaultNextSpeed = std::numeric_limits<double>::max();
1377 int leftmostOnEdge = (int)sublaneSides.size() - 1;
1378 while (leftmostOnEdge > 0 && sublaneSides[leftmostOnEdge] > leftVehSide) {
1381 int rightmostOnEdge = leftmostOnEdge;
1382 while (rightmostOnEdge > 0 && sublaneSides[rightmostOnEdge] > rightVehSide +
NUMERICAL_EPS) {
1384 #ifdef DEBUG_WANTSCHANGE 1386 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1387 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1393 #ifdef DEBUG_WANTSCHANGE 1395 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1396 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1399 double maxGain = -std::numeric_limits<double>::max();
1400 double maxGainRight = -std::numeric_limits<double>::max();
1401 double maxGainLeft = -std::numeric_limits<double>::max();
1402 double latDistNice = std::numeric_limits<double>::max();
1405 const double leftMax =
MAX2(
1408 assert(leftMax <= edge.
getWidth());
1409 int sublaneCompact =
MAX2(iMin, rightmostOnEdge - 1);
1411 #ifdef DEBUG_WANTSCHANGE 1413 <<
" checking sublanes rightmostOnEdge=" << rightmostOnEdge
1414 <<
" leftmostOnEdge=" << leftmostOnEdge
1416 <<
" leftMax=" << leftMax
1417 <<
" sublaneCompact=" << sublaneCompact
1420 for (
int i = iMin; i < (int)sublaneSides.size(); ++i) {
1421 if (sublaneSides[i] + vehWidth < leftMax) {
1427 while (vMin > 0 && j < (
int)sublaneSides.size() && sublaneSides[j] < sublaneSides[i] + vehWidth) {
1433 const double currentLatDist = sublaneSides[i] - rightVehSide;
1435 if (relativeGain > maxGain) {
1436 maxGain = relativeGain;
1439 latDist = currentLatDist;
1440 #ifdef DEBUG_WANTSCHANGE 1442 std::cout <<
" i=" << i <<
" newLatDist=" << latDist <<
" relGain=" << relativeGain <<
"\n";
1448 if (currentLatDist > 0
1453 latDist = currentLatDist;
1456 #ifdef DEBUG_WANTSCHANGE 1458 std::cout <<
" i=" << i <<
" rightmostOnEdge=" << rightmostOnEdge <<
" vMin=" << vMin <<
" relGain=" << relativeGain <<
" sublaneCompact=" << sublaneCompact <<
" curLatDist=" << currentLatDist <<
"\n";
1462 maxGainRight =
MAX2(maxGainRight, relativeGain);
1464 maxGainLeft =
MAX2(maxGainLeft, relativeGain);
1466 const double subAlignDist = sublaneSides[i] - rightVehSide;
1467 if (fabs(subAlignDist) < fabs(latDistNice)) {
1468 latDistNice = subAlignDist;
1469 #ifdef DEBUG_WANTSCHANGE 1471 <<
" nicest sublane=" << i
1472 <<
" side=" << sublaneSides[i]
1473 <<
" rightSide=" << rightVehSide
1474 <<
" latDistNice=" << latDistNice
1475 <<
" maxGainR=" << maxGainRight
1476 <<
" maxGainL=" << maxGainLeft
1483 if (maxGainRight != -std::numeric_limits<double>::max()) {
1484 #ifdef DEBUG_WANTSCHANGE 1490 #ifdef DEBUG_WANTSCHANGE 1496 if (maxGainLeft != -std::numeric_limits<double>::max()) {
1497 #ifdef DEBUG_WANTSCHANGE 1503 #ifdef DEBUG_WANTSCHANGE 1510 if ((fabs(maxGainRight) <
NUMERICAL_EPS || maxGainRight == -std::numeric_limits<double>::max())
1511 && (right || (alternatives &
LCA_RIGHT) == 0)) {
1514 if ((fabs(maxGainLeft) <
NUMERICAL_EPS || maxGainLeft == -std::numeric_limits<double>::max())
1515 && (left || (alternatives &
LCA_LEFT) == 0)) {
1520 #ifdef DEBUG_WANTSCHANGE 1523 <<
" defaultNextSpeed=" << defaultNextSpeed
1524 <<
" maxGain=" << maxGain
1525 <<
" maxGainRight=" << maxGainRight
1526 <<
" maxGainLeft=" << maxGainLeft
1527 <<
" latDist=" << latDist
1528 <<
" latDistNice=" << latDistNice
1529 <<
" sublaneCompact=" << sublaneCompact
1535 if (right && maxGain >= 0 && latDist <= 0) {
1542 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1544 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1545 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1547 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1548 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1553 #ifdef DEBUG_WANTSCHANGE 1556 <<
" considering keepRight:" 1558 <<
" neighDist=" << neighDist
1560 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1562 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1563 <<
" acceptanceTime=" << acceptanceTime
1564 <<
" fullSpeedGap=" << fullSpeedGap
1565 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1566 <<
" dProb=" << deltaProb
1577 latDist = latLaneDist;
1578 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1579 leaders, followers, blockers,
1580 neighLeaders, neighFollowers, neighBlockers);
1586 #ifdef DEBUG_WANTSCHANGE 1591 <<
" neighDist=" << neighDist
1594 <<
" latDist=" << latDist
1603 int blockedFully = 0;
1604 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1605 leaders, followers, blockers,
1606 neighLeaders, neighFollowers, neighBlockers,
1607 nullptr,
nullptr,
false, 0, &blockedFully);
1616 #ifdef DEBUG_WANTSCHANGE 1621 <<
" latDist=" << latDist
1622 <<
" neighDist=" << neighDist
1625 <<
" stayInLane=" << stayInLane
1636 int blockedFully = 0;
1637 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1638 leaders, followers, blockers,
1639 neighLeaders, neighFollowers, neighBlockers,
1640 nullptr,
nullptr,
false, 0, &blockedFully);
1649 double latDistSublane = 0.;
1651 const double halfVehWidth =
getWidth() * 0.5;
1654 && bestLaneOffset == 0
1674 #ifdef DEBUG_WANTSCHANGE 1688 switch (turnInfo.second) {
1717 latDistSublane = latDistNice;
1720 latDistSublane = sublaneSides[sublaneCompact] - rightVehSide;
1728 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) || defined(DEBUG_MANEUVER) 1733 <<
" latDist=" << latDist
1734 <<
" latDistSublane=" << latDistSublane
1735 <<
" relGainSublane=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed)
1736 <<
" maneuverDist=" << maneuverDist
1751 && ((myManeuverDist < 0 && latDistSublane > 0) || (
myManeuverDist > 0 && latDistSublane < 0))) {
1754 latDist = latDistSublane;
1759 #ifdef DEBUG_WANTSCHANGE 1762 <<
" latDist=" << latDist
1767 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1768 leaders, followers, blockers,
1769 neighLeaders, neighFollowers, neighBlockers);
1796 #ifdef DEBUG_WANTSCHANGE 1813 if ((*blocked) !=
nullptr) {
1815 #ifdef DEBUG_SLOWDOWN 1839 (*blocked)->getCarFollowModel().getMaxDecel()));
1850 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1866 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1878 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1884 <<
" potential=" << potential
1900 <<
"vSafe=" << vSafe <<
" -> accel=" << accel <<
"\n";
1910 const MSLane* lane = lanes[laneIndex];
1912 assert(preb.size() == lanes.size());
1914 for (
int sublane = 0; sublane < (int)ahead.
numSublanes(); ++sublane) {
1915 const int edgeSublane = sublane + sublaneOffset;
1923 const MSVehicle* leader = ahead[sublane].first;
1924 const double gap = ahead[sublane].second;
1926 if (leader ==
nullptr) {
1935 #ifdef DEBUG_EXPECTED_SLSPEED 1937 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" updateExpectedSublaneSpeeds edgeSublane=" << edgeSublane <<
" leader=" << leader->
getID() <<
" gap=" << gap <<
" vSafe=" << vSafe <<
"\n";
1940 const double deltaV = vMax - leader->
getSpeed();
1941 if (deltaV > 0 && gap / deltaV < 5) {
1950 double foeRight, foeLeft;
1954 if (leader.first != 0) {
1957 vSafe =
MIN2(vSafe, vSafePed);
1960 vSafe =
MIN2(vMax, vSafe);
1962 myExpectedSublaneSpeeds[edgeSublane] = memoryFactor * myExpectedSublaneSpeeds[edgeSublane] + (1 - memoryFactor) * vSafe;
1974 double result = std::numeric_limits<double>::max();
1977 const double vehWidth =
getWidth();
1979 const double leftVehSide = rightVehSide + vehWidth;
1980 for (
int i = 0; i < (int)sublaneSides.size(); ++i) {
1981 if (
overlap(rightVehSide, leftVehSide, sublaneSides[i], sublaneSides[i] + res)) {
1987 return result - defaultNextSpeed;
1994 double maxLength = -1;
1996 if (ldi[i].first != 0) {
1997 const double length = ldi[i].first->getVehicleType().getLength();
1998 if (length > maxLength) {
2011 double minSpeed = std::numeric_limits<double>::max();
2013 if (ldi[i].first != 0) {
2014 const double speed = ldi[i].first->getSpeed();
2015 if (speed < minSpeed) {
2033 std::vector<CLeaderDist>* collectLeadBlockers,
2034 std::vector<CLeaderDist>* collectFollowBlockers,
2035 bool keepLatGapManeuver,
2037 int* retBlockedFully) {
2039 if (!keepLatGapManeuver) {
2041 maneuverDist = latDist;
2044 latDist =
MAX2(
MIN2(latDist, maxDist), -maxDist);
2052 if (laneOffset != 0) {
2063 if (laneOffset != 0) {
2067 #ifdef DEBUG_BLOCKING 2069 std::cout <<
" checkBlocking latDist=" << latDist <<
" mySafeLatDistRight=" << mySafeLatDistRight <<
" mySafeLatDistLeft=" << mySafeLatDistLeft <<
"\n";
2079 }
else if (!forcedTraCIChange) {
2080 latDist =
MAX2(latDist, -mySafeLatDistRight);
2085 }
else if (!forcedTraCIChange) {
2086 latDist =
MIN2(latDist, mySafeLatDistLeft);
2091 #ifdef DEBUG_BLOCKING 2107 if (laneOffset != 0) {
2110 mySafeLatDistRight, mySafeLatDistLeft, collectLeadBlockers);
2113 mySafeLatDistRight, mySafeLatDistLeft, collectFollowBlockers);
2116 int blockedFully = 0;
2121 if (laneOffset != 0) {
2124 mySafeLatDistRight, mySafeLatDistLeft, collectLeadBlockers);
2127 mySafeLatDistRight, mySafeLatDistLeft, collectFollowBlockers);
2129 if (retBlockedFully !=
nullptr) {
2130 *retBlockedFully = blockedFully;
2137 blocked |= blockedFully;
2142 if (collectFollowBlockers !=
nullptr && collectLeadBlockers !=
nullptr) {
2144 for (std::vector<CLeaderDist>::const_iterator it2 = collectLeadBlockers->begin(); it2 != collectLeadBlockers->end(); ++it2) {
2145 for (std::vector<CLeaderDist>::iterator it = collectFollowBlockers->begin(); it != collectFollowBlockers->end();) {
2146 if ((*it2).first == (*it).first) {
2147 #ifdef DEBUG_BLOCKING 2149 std::cout <<
" removed follower " << (*it).first->getID() <<
" because it is already a leader\n";
2152 it = collectFollowBlockers->erase(it);
2166 double latDist,
double foeOffset,
bool leaders,
LaneChangeAction blockType,
2167 double& safeLatGapRight,
double& safeLatGapLeft,
2168 std::vector<CLeaderDist>* collectBlockers)
const {
2170 const double vehWidth =
getWidth();
2172 const double leftVehSide = rightVehSide + vehWidth;
2173 const double rightVehSideDest = rightVehSide + latDist;
2174 const double leftVehSideDest = leftVehSide + latDist;
2175 const double rightNoOverlap =
MIN2(rightVehSideDest, rightVehSide);
2176 const double leftNoOverlap =
MAX2(leftVehSideDest, leftVehSide);
2177 #ifdef DEBUG_BLOCKING 2179 std::cout <<
" checkBlockingVehicles" 2180 <<
" latDist=" << latDist
2181 <<
" foeOffset=" << foeOffset
2182 <<
" vehRight=" << rightVehSide
2183 <<
" vehLeft=" << leftVehSide
2184 <<
" rightNoOverlap=" << rightNoOverlap
2185 <<
" leftNoOverlap=" << leftNoOverlap
2186 <<
" destRight=" << rightVehSideDest
2187 <<
" destLeft=" << leftVehSideDest
2188 <<
" leaders=" << leaders
2194 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2196 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2197 const MSVehicle* leader = vehDist.first;
2200 std::swap(leader, follower);
2203 double foeRight, foeLeft;
2205 const bool overlapBefore =
overlap(rightVehSide, leftVehSide, foeRight, foeLeft);
2206 const bool overlapDest =
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft);
2207 const bool overlapAny =
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft);
2208 #ifdef DEBUG_BLOCKING 2210 std::cout <<
" foe=" << vehDist.first->getID()
2211 <<
" gap=" << vehDist.second
2213 <<
" foeRight=" << foeRight
2214 <<
" foeLeft=" << foeLeft
2215 <<
" overlapBefore=" << overlapBefore
2216 <<
" overlap=" << overlapAny
2217 <<
" overlapDest=" << overlapDest
2222 if (vehDist.second < 0) {
2223 if (overlapBefore && !overlapDest) {
2224 #ifdef DEBUG_BLOCKING 2226 std::cout <<
" ignoring current overlap to come clear\n";
2230 #ifdef DEBUG_BLOCKING 2236 if (collectBlockers ==
nullptr) {
2239 collectBlockers->push_back(vehDist);
2255 const double expectedGap =
MSCFModel::gapExtrapolation(timeTillAction, vehDist.second, leader->
getSpeed(), follower->
getSpeed(), leaderAccel, followerAccel, std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
2258 const double followerExpectedSpeed = follower->
getSpeed() + timeTillAction * followerAccel;
2259 const double leaderExpectedSpeed =
MAX2(0., leader->
getSpeed() + timeTillAction * leaderAccel);
2262 #if defined(DEBUG_ACTIONSTEPS) && defined(DEBUG_BLOCKING) 2264 std::cout <<
" timeTillAction=" << timeTillAction
2265 <<
" followerAccel=" << followerAccel
2266 <<
" followerExpectedSpeed=" << followerExpectedSpeed
2267 <<
" leaderAccel=" << leaderAccel
2268 <<
" leaderExpectedSpeed=" << leaderExpectedSpeed
2269 <<
"\n gap=" << vehDist.second
2270 <<
" gapChange=" << (expectedGap - vehDist.second)
2271 <<
" expectedGap=" << expectedGap
2272 <<
" expectedSecureGap=" << expectedSecureGap
2273 <<
" safeLatGapLeft=" << safeLatGapLeft
2274 <<
" safeLatGapRight=" << safeLatGapRight
2281 if (expectedGap < secureGap2) {
2283 if (foeRight > leftVehSide) {
2284 safeLatGapLeft =
MIN2(safeLatGapLeft, foeRight - leftVehSide);
2285 }
else if (foeLeft < rightVehSide) {
2286 safeLatGapRight =
MIN2(safeLatGapRight, rightVehSide - foeLeft);
2289 #ifdef DEBUG_BLOCKING 2291 std::cout <<
" blocked by " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2292 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor()
2293 <<
" safeLatGapLeft=" << safeLatGapLeft <<
" safeLatGapRight=" << safeLatGapRight
2297 result |= blockType;
2298 if (collectBlockers ==
nullptr) {
2301 collectBlockers->push_back(vehDist);
2303 #ifdef DEBUG_BLOCKING 2304 }
else if (
gDebugFlag2 && expectedGap < expectedSecureGap) {
2305 std::cout <<
" ignore blocker " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2306 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor() <<
"\n";
2324 const double leftVehSide = rightVehSide + vehWidth;
2325 #ifdef DEBUG_BLOCKING 2327 std::cout <<
" updateCFRelated foeOffset=" << foeOffset <<
" vehicles=" << vehicles.
toString() <<
"\n";
2330 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2332 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2333 double foeRight, foeLeft;
2335 if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft) && (vehDist.second >= 0
2341 && -vehDist.second < vehDist.first->getVehicleType().getMinGap()
2344 #ifdef DEBUG_BLOCKING 2346 std::cout <<
" ignoring cfrelated foe=" << vehDist.first->getID() <<
" gap=" << vehDist.second
2348 <<
" foeOffset=" << foeOffset
2349 <<
" egoR=" << rightVehSide <<
" egoL=" << leftVehSide
2350 <<
" iR=" << foeRight <<
" iL=" << foeLeft
2365 assert(right <= left);
2366 assert(right2 <= left2);
2374 if (sd1.
state == 0) {
2376 }
else if (sd2.
state == 0) {
2384 #ifdef DEBUG_WANTSCHANGE 2390 <<
" dir1=" << sd1.
dir 2394 <<
" dir2=" << sd2.
dir 2402 return (!can1 && can2 && sd1.
sameDirection(sd2)) ? sd2 : sd1;
2406 return (!can2 && can1 && sd1.
sameDirection(sd2)) ? sd1 : sd2;
2414 }
else if (sd2.
dir == 0) {
2419 assert(sd1.
dir == -1);
2420 assert(sd2.
dir == 1);
2423 }
else if (sd2.
latDist >= 0) {
2431 return can1 ? sd1 : sd2;
2454 const std::vector<MSVehicle::LaneQ>& preb,
2463 int roundaboutEdgesAhead,
2467 const bool right = (laneOffset == -1);
2468 const bool left = (laneOffset == 1);
2480 #ifdef DEBUG_STRATEGIC_CHANGE 2485 <<
" laDist=" << laDist
2486 <<
" currentDist=" << currentDist
2487 <<
" usableDist=" << usableDist
2488 <<
" bestLaneOffset=" << bestLaneOffset
2489 <<
" best.length=" << best.
length 2490 <<
" maxJam=" << maxJam
2491 <<
" neighLeftPlace=" << neighLeftPlace
2496 if (laneOffset != 0 && changeToBest && bestLaneOffset == curr.
bestLaneOffset 2499 latDist = latLaneDist;
2516 #ifdef DEBUG_STRATEGIC_CHANGE 2519 <<
" avoid overtaking on the right nv=" << nv->
getID()
2529 if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
2536 #ifdef DEBUG_STRATEGIC_CHANGE 2538 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
2544 && bestLaneOffset == 0
2547 && roundaboutEdgesAhead == 0
2552 #ifdef DEBUG_STRATEGIC_CHANGE 2554 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
2559 && bestLaneOffset == 0
2565 #ifdef DEBUG_STRATEGIC_CHANGE 2567 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
2582 if (*it ==
nullptr) {
2586 if (shadow ==
nullptr || currentShadowDist >= requiredDist) {
2589 currentShadowDist += shadow->
getLength();
2591 #ifdef DEBUG_STRATEGIC_CHANGE 2596 if (currentShadowDist < requiredDist && currentShadowDist < usableDist) {
2599 #ifdef DEBUG_STRATEGIC_CHANGE 2601 std::cout <<
" must change for shadowLane end latDist=" << latDist <<
" myLeftSpace=" <<
myLeftSpace <<
"\n";
2609 #if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI) 2621 }
else if (((retTraCI &
LCA_RIGHT) != 0 && laneOffset < 0)
2622 || ((retTraCI &
LCA_LEFT) != 0 && laneOffset > 0)) {
2624 latDist = latLaneDist;
2627 #if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI) 2629 std::cout <<
" reqAfterInfluence=" << ret <<
" ret=" << ret <<
"\n";
2653 double& maneuverDist,
2689 const bool stayInLane = laneOffset == 0 || ((state &
LCA_STRATEGIC) != 0 && (state &
LCA_STAY) != 0);
2690 const double oldLatDist = latDist;
2693 const double halfWidth =
getWidth() * 0.5;
2699 double surplusGapRight = oldCenter - halfWidth;
2701 #ifdef DEBUG_KEEP_LATGAP 2703 std::cout <<
"\n " <<
SIMTIME <<
" keepLatGap() laneOffset=" << laneOffset
2704 <<
" latDist=" << latDist
2707 <<
" gapFactor=" << gapFactor
2708 <<
" stayInLane=" << stayInLane <<
"\n" 2709 <<
" stayInEdge: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2713 if (surplusGapLeft < 0 || surplusGapRight < 0) {
2723 if (laneOffset != 0) {
2728 #ifdef DEBUG_KEEP_LATGAP 2730 std::cout <<
" minGapLat: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n" 2739 if (stayInLane || laneOffset == 1) {
2745 if (stayInLane || laneOffset == -1) {
2751 #ifdef DEBUG_KEEP_LATGAP 2753 std::cout <<
" stayInLane: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2757 if (surplusGapRight + surplusGapLeft < 0) {
2762 const double equalDeficit = 0.5 * (surplusGapLeft + surplusGapRight);
2763 if (surplusGapRight < surplusGapLeft) {
2765 const double delta =
MIN2(equalDeficit - surplusGapRight, physicalGapLeft);
2767 maneuverDist = delta;
2768 #ifdef DEBUG_KEEP_LATGAP 2770 std::cout <<
" insufficient latSpace, move left: delta=" << delta <<
"\n";
2775 const double delta =
MIN2(equalDeficit - surplusGapLeft, physicalGapRight);
2777 maneuverDist = -delta;
2778 #ifdef DEBUG_KEEP_LATGAP 2780 std::cout <<
" insufficient latSpace, move right: delta=" << delta <<
"\n";
2786 latDist =
MAX2(
MIN2(latDist, surplusGapLeft), -surplusGapRight);
2787 maneuverDist =
MAX2(
MIN2(maneuverDist, surplusGapLeft), -surplusGapRight);
2788 #ifdef DEBUG_KEEP_LATGAP 2790 std::cout <<
" adapted latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
" (old=" << oldLatDist <<
")\n";
2800 #ifdef DEBUG_KEEP_LATGAP 2802 std::cout <<
" traci influenced latDist=" << latDist <<
"\n";
2808 const bool traciChange = (state &
LCA_TRACI) != 0;
2809 if (nonSublaneChange && !traciChange) {
2811 #ifdef DEBUG_KEEP_LATGAP 2813 std::cout <<
" wanted changeToLeft oldLatDist=" << oldLatDist <<
", blocked latGap changeToRight\n";
2816 latDist = oldLatDist;
2819 #ifdef DEBUG_KEEP_LATGAP 2821 std::cout <<
" wanted changeToRight oldLatDist=" << oldLatDist <<
", blocked latGap changeToLeft\n";
2824 latDist = oldLatDist;
2834 #ifdef DEBUG_KEEP_LATGAP 2836 std::cout <<
" latDistUpdated=" << latDist <<
" oldLatDist=" << oldLatDist <<
"\n";
2839 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset, leaders, followers, blockers, neighLeaders, neighFollowers, neighBlockers,
nullptr,
nullptr, nonSublaneChange);
2842 state = (state & ~LCA_STAY);
2853 #if defined(DEBUG_KEEP_LATGAP) || defined(DEBUG_STATE) 2855 std::cout <<
" latDist2=" << latDist
2869 double& surplusGapRight,
double& surplusGapLeft,
2870 bool saveMinGap,
double netOverlap,
2872 std::vector<CLeaderDist>* collectBlockers) {
2877 if (others[i].first != 0 && others[i].second <= 0
2879 && (netOverlap == 0 || others[i].second + others[i].first->getVehicleType().getMinGap() < netOverlap)) {
2883 double foeRight, foeLeft;
2885 const double foeCenter = foeRight + 0.5 * res;
2886 const double gap =
MIN2(fabs(foeRight - oldCenter), fabs(foeLeft - oldCenter)) - halfWidth;
2889 const double currentMinGap = desiredMinGap * gapFactor;
2900 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP) 2902 std::cout <<
" updateGaps" 2904 <<
" foe=" << foe->
getID()
2905 <<
" foeRight=" << foeRight
2906 <<
" foeLeft=" << foeLeft
2907 <<
" oldCenter=" << oldCenter
2908 <<
" gap=" << others[i].second
2909 <<
" latgap=" << gap
2910 <<
" currentMinGap=" << currentMinGap
2911 <<
" surplusGapRight=" << surplusGapRight
2912 <<
" surplusGapLeft=" << surplusGapLeft
2920 if (foeCenter < oldCenter) {
2922 surplusGapRight =
MIN3(surplusGapRight, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
2925 surplusGapLeft =
MIN3(surplusGapLeft, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
2928 if (foeCenter < oldCenter) {
2929 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP) 2931 std::cout <<
" new minimum rightGap=" << gap <<
"\n";
2936 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP) 2938 std::cout <<
" new minimum leftGap=" << gap <<
"\n";
2944 if (collectBlockers !=
nullptr) {
2946 if ((foeCenter < oldCenter && latDist < 0 && gap < (desiredMinGap - latDist))
2947 || (foeCenter > oldCenter && latDist > 0 && gap < (desiredMinGap + latDist))) {
2948 collectBlockers->push_back(others[i]);
2965 int currentDirection =
mySpeedLat >= 0 ? 1 : -1;
2966 int directionWish = latDist >= 0 ? 1 : -1;
2970 #ifdef DEBUG_MANEUVER 2974 <<
" computeSpeedLat()" 2975 <<
" currentDirection=" << currentDirection
2976 <<
" directionWish=" << directionWish
2982 if (directionWish == 1) {
2993 double speedAccelSafe = latDist * speedAccel >= 0 ? speedAccel : 0;
3001 if (maneuverDist * latDist > 0) {
3002 maneuverDist = fullLatDist;
3005 #ifdef DEBUG_MANEUVER 3010 <<
" latDist=" << latDist
3011 <<
" maneuverDist=" << maneuverDist
3014 <<
" fullLatDist=" << fullLatDist
3015 <<
" speedAccel=" << speedAccel
3016 <<
" speedDecel=" << speedDecel
3017 <<
" speedBound=" << speedBound
3021 if (speedDecel * speedAccel <= 0 && (
3023 (latDist >= 0 && speedAccel >= speedBound && speedBound >= speedDecel)
3024 || (latDist <= 0 && speedAccel <= speedBound && speedBound <= speedDecel))) {
3026 #ifdef DEBUG_MANEUVER 3028 std::cout <<
" computeSpeedLat a)\n";
3035 #ifdef DEBUG_MANEUVER 3037 std::cout <<
" computeSpeedLat b)\n";
3040 return speedAccelSafe;
3044 if ((fabs(minDistAccel) < fabs(fullLatDist)) || (fabs(minDistAccel - fullLatDist) <
NUMERICAL_EPS)) {
3045 #ifdef DEBUG_MANEUVER 3047 std::cout <<
" computeSpeedLat c)\n";
3052 #ifdef DEBUG_MANEUVER 3054 std::cout <<
" minDistAccel=" << minDistAccel <<
"\n";
3059 if ((fabs(minDistCurrent) < fabs(fullLatDist)) || (fabs(minDistCurrent - fullLatDist) <
NUMERICAL_EPS)) {
3060 #ifdef DEBUG_MANEUVER 3062 std::cout <<
" computeSpeedLat d)\n";
3069 #ifdef DEBUG_MANEUVER 3071 std::cout <<
" computeSpeedLat e)\n";
3074 return speedDecelSafe;
3083 double maneuverDist) {
3086 double secondsToLeaveLane;
3107 double nextLeftSpace;
3108 if (nextActionStepSpeed > 0.) {
3116 const double avoidArrivalSpeed = nextActionStepSpeed +
TS *
MSCFModel::avoidArrivalAccel(nextLeftSpace, secondsToLeaveLane - timeTillActionStep, nextActionStepSpeed);
3122 #ifdef DEBUG_MANEUVER 3126 <<
" avoidArrivalSpeed=" << avoidArrivalSpeed
3129 <<
"\n nextLeftSpace=" << nextLeftSpace
3130 <<
" nextLeftSpace=" << nextActionStepSpeed
3131 <<
" nextActionStepRemainingSeconds=" << secondsToLeaveLane - timeTillActionStep
3139 myCommittedSpeed = 0;
3141 #ifdef DEBUG_MANEUVER 3145 <<
" secondsToLeave=" << secondsToLeaveLane
3147 <<
" committed=" << myCommittedSpeed
3167 const double vehWidth =
getWidth();
3169 const double leftVehSide = rightVehSide + vehWidth;
3170 const double rightVehSideDest = rightVehSide + latDist;
3171 const double leftVehSideDest = leftVehSide + latDist;
3172 #ifdef DEBUG_MANEUVER 3174 std::cout <<
" commitFollowSpeed" 3175 <<
" latDist=" << latDist
3176 <<
" foeOffset=" << foeOffset
3177 <<
" vehRight=" << rightVehSide
3178 <<
" vehLeft=" << leftVehSide
3179 <<
" destRight=" << rightVehSideDest
3180 <<
" destLeft=" << leftVehSideDest
3186 if (vehDist.first != 0) {
3187 const MSVehicle* leader = vehDist.first;
3189 double foeRight, foeLeft;
3191 #ifdef DEBUG_MANEUVER 3193 std::cout <<
" foe=" << vehDist.first->getID()
3194 <<
" gap=" << vehDist.second
3196 <<
" foeRight=" << foeRight
3197 <<
" foeLeft=" << foeLeft
3198 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
3199 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
3203 if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
3205 assert(vehDist.second >= 0);
3208 speed =
MIN2(speed, vSafe);
3209 #ifdef DEBUG_MANEUVER 3211 std::cout <<
" case1 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3214 }
else if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)) {
3219 speed =
MIN2(speed, vSafe);
3220 #ifdef DEBUG_MANEUVER 3222 std::cout <<
" case2 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3318 const std::pair<MSVehicle*, double>& leader,
3319 const std::pair<MSVehicle*, double>& neighLead,
3320 const std::pair<MSVehicle*, double>& neighFollow,
3322 const std::vector<MSVehicle::LaneQ>& preb,
3328 #ifdef DEBUG_WANTSCHANGE 3330 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 3337 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3351 double maneuverDist;
3354 leaders, followers, blockers,
3355 neighLeaders, neighFollowers, neighBlockers,
3357 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
3363 result |=
getLCA(result, latDist);
3365 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) 3370 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3371 << ((result &
LCA_URGENT) ?
" (urgent)" :
"")
3377 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
void * inform(void *info, MSVehicle *sender)
The link is a partial left direction.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
static double gLateralResolution
void initDerivedParameters()
init cached parameters derived directly from model parameters
const std::vector< double > getSubLaneSides() const
Returns the right side offsets of this edge's sublanes.
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i...
saves leader/follower vehicles and their distances relative to an ego vehicle
double myChangeProbThresholdLeft
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
void msg(const CLeaderDist &cld, double speed, int state)
send a speed recommendation to the given vehicle
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key ...
double mySpeedGainProbabilityLeft
a value for tracking the probability that a change to the left is beneficial
The action is due to the default of keeping right "Rechtsfahrgebot".
double myLastLateralGapRight
The action is done to help someone else.
#define RELGAIN_NORMALIZATION_MIN_SPEED
std::set< const MSVehicle * > myCFRelated
set of vehicles that are in a car-following relationship with ego (leader of followers) ...
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
virtual std::string toString() const
print a debugging representation
#define ROUNDABOUT_DIST_BONUS
int myPreviousState
lane changing state from the previous simulation step
double informLeaders(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds)
MSLane * getLane() const
Returns the lane the vehicle is on.
bool myCanChangeFully
whether the current lane changing maneuver can be finished in a single step
double computeGapFactor(int state) const
compute the gap factor for the given state
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 bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
The vehicle is blocked by left follower.
At the leftmost side of the lane.
int gPrecision
the precision for floating point outputs
LateralAlignment getPreferredLateralAlignment() const
Get vehicle's preferred lateral alignment.
double getManeuverDist() const
Returns the remaining unblocked distance for the current maneuver. (only used by sublane model) ...
int checkBlockingVehicles(const MSVehicle *ego, const MSLeaderDistanceInfo &vehicles, double latDist, double foeOffset, bool leaders, LaneChangeAction blockType, double &safeLatGapRight, double &safeLatGapLeft, std::vector< CLeaderDist > *collectBlockers=0) const
check whether any of the vehicles overlaps with ego
const double SUMO_const_laneWidth
The car-following model abstraction.
double computeSpeedLat(double latDist, double &maneuverDist)
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
int checkBlocking(const MSLane &neighLane, double &latDist, double &maneuverDist, int laneOffset, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, std::vector< CLeaderDist > *collectLeadBlockers=0, std::vector< CLeaderDist > *collectFollowBlockers=0, bool keepLatGapManeuver=false, double gapFactor=0, int *retBlockedFully=0)
restrict latDist to permissible speed and determine blocking state depending on that distance ...
double getPositionOnLane() const
Get the vehicle's position along the lane.
double mySpeedLossProbThreshold
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
void setOwnState(const int state)
static CLeaderDist getSlowest(const MSLeaderDistanceInfo &ldi)
get the slowest vehicle in the given info
int getBestLaneOffset() const
The link is a 180 degree turn.
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
std::vector< double > myExpectedSublaneSpeeds
expected travel speeds on all sublanes on the current edge(!)
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
double myTimeToImpatience
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
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
const MSRoute & getRoute() const
Returns the current route.
double getMinGapLat() const
Get the minimum lateral gap that vehicles of this type maintain.
double myMaxSpeedLatStanding
const MSEdge * getLastEdge() const
returns the destination edge
static const double NO_NEIGHBOR
const std::string & getID() const
Returns the id.
bool sameDirection(const StateAndDist &other) const
align with the closest sublane border
static double avoidArrivalAccel(double dist, double time, double speed)
Computes the acceleration needed to arrive not before the given time.
double length
The overall length which may be driven when using this lane without a lane change.
bool debugVehicle() const
whether the current vehicles shall be debugged
The action is due to the wish to be faster (tactical lc)
double getWidth() const
Returns the lane's width.
#define UNUSED_PARAMETER(x)
MSLCM_SL2015(MSVehicle &v)
used by the sublane model
#define LCA_RIGHT_IMPATIENCE
The link is a (hard) left direction.
double myTurnAlignmentDist
LateralAlignment
Numbers representing special SUMO-XML-attribute values Information how vehicles align themselves with...
double myChangeProbThresholdRight
MSAbstractLaneChangeModel & getLaneChangeModel()
int keepLatGap(int state, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, int laneOffset, double &latDist, double &maneuverDist, int &blocked)
check whether lateral gap requirements are met override the current maneuver if necessary ...
#define MAX_ONRAMP_LENGTH
#define GAIN_PERCEPTION_THRESHOLD
#define ARRIVALPOS_LAT_THRESHOLD
The link is a straight direction.
double mySafeLatDistRight
the lateral distance the vehicle can safely move in the currently considered direction ...
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Needs to stay on the current lane.
void saveBlockerLength(const MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
const LaneChangeModel myModel
the type of this model
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
double getWidth() const
return the widht of this vehicle (padded for numerical stability)
static bool overlap(double right, double left, double right2, double left2)
return whether the given intervals overlap
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
A class responsible for exchanging messages between cars involved in lane-change interaction.
StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const
decide in which direction to move in case both directions are desirable
A road/street connecting two junctions.
void commitManoeuvre(int blocked, int blockedFully, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, const MSLane &neighLane, double maneuverDist)
commit to lane change maneuvre potentially overriding safe speed
double myLeadingBlockerLength
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
int getIndex() const
Returns the lane's index.
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points...
double myManeuverDist
The complete lateral distance the vehicle wants to travel to finish its maneuver Only used by sublane...
double commitFollowSpeed(double speed, double latDist, double secondsToLeaveLane, const MSLeaderDistanceInfo &leaders, double foeOffset) const
compute speed when committing to an urgent change that is safe in regard to leading vehicles ...
blocked in all directions
void updateCFRelated(const MSLeaderDistanceInfo &vehicles, double foeOffset, bool leaders)
find leaders/followers that are already in a car-following relationship with ego
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane ...
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 double brakeGapEuler(const double speed, const double decel, const double headwayTime)
At the center of the lane.
static MSPModel * getModel()
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
const MSEdge * myLastEdge
expected travel speeds on all sublanes on the current edge(!)
double informLeader(int blocked, int dir, const CLeaderDist &neighLead, double remainingSeconds)
static LaneChangeAction getLCA(int state, double latDist)
compute lane change action from desired lateral distance
void informFollowers(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds, double plannedSpeed)
call informFollower for multiple followers
double myMaxSpeedLatFactor
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
double getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0) ...
const std::pair< double, LinkDirection > & getNextTurn()
Get the distance and direction of the next upcoming turn for the vehicle (within its look-ahead range...
int wantsChangeSublane(int laneOffset, LaneChangeAction alternatives, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked, double &latDist, double &maneuverDist, int &blocked)
Called to examine whether the vehicle wants to change with the given laneOffset (using the sublane mo...
At the rightmost side of the lane.
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
#define KEEP_RIGHT_ACCEPTANCE
The link is a (hard) right direction.
The action is needed to follow the route (navigational lc)
int _wantsChangeSublane(int laneOffset, LaneChangeAction alternatives, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked, double &latDist, double &maneuverDist, int &blocked)
helper function for doing the actual work
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 ...
bool hasInfluencer() const
virtual void updateSafeLatDist(const double travelledLatDist)
Updates the value of safe lateral distances (mySafeLatDistLeft and mySafeLatDistRight) during maneuve...
double getMinGap() const
Get the free space in front of vehicles of this class.
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
int myOwnState
The current state of the vehicle.
maintain the current alignment
bool isInternal() const
return whether this edge is an internal edge
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
#define LOOK_AHEAD_SPEED_MEMORY
#define LOOK_AHEAD_MIN_SPEED
static CLeaderDist getLongest(const MSLeaderDistanceInfo &ldi)
get the longest vehicle in the given info
The link is a partial right direction.
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
const MSLane * lane
The lane to stop at.
double myCooperativeParam
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getRightSideOnEdge() const
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< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
double computeSpeedGain(double latDistSublane, double defaultNextSpeed) const
compute speedGain when moving by the given amount
int getRightmostSublane() const
std::pair< const MSPerson *, double > PersonDist
int checkStrategicChange(int ret, int laneOffset, const std::vector< MSVehicle::LaneQ > &preb, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, int currIdx, int bestLaneOffset, bool changeToBest, double currentDist, double neighDist, double laDist, int roundaboutEdgesAhead, double latLaneDist, double &latDist)
compute strategic lane change actions TODO: Better documentation, refs #2
bool hasStoppedVehicle() const
whether a stopped vehicle is leader
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
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.
std::pair< const MSVehicle *, double > CLeaderDist
Influencer & getInfluencer()
Returns the velocity/lane influencer.
LaneChangeAction
The state of a vehicle's lane-change behavior.
virtual void setOwnState(const int state)
virtual void setMaxDecel(double decel)
Sets a new value for maximal comfortable deceleration [m/s^2].
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.
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 ...
#define SPEEDGAIN_MEMORY_FACTOR
bool isActive() const
Returns whether the current simulation step is an action point for the vehicle.
double myKeepRightProbability
The vehicle is blocked being overlapping.
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
std::vector< MSLane * > bestContinuations
void getSublaneBorders(int sublane, double latOffset, double &rightSide, double &leftSide) const
static double estimateArrivalTime(double dist, double speed, double maxSpeed, double accel)
Computes the time needed to travel a distance dist given an initial speed and constant acceleration...
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
void informFollower(int blocked, int dir, const CLeaderDist &neighFollow, double remainingSeconds, double plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
double mySpeedLat
the current lateral speed
No information given; use default.
double getLength() const
Get vehicle's length [m].
#define SPEEDGAIN_DECAY_FACTOR
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
align with the rightmost sublane that allows keeping the current speed
virtual void prepareStep()
bool allowsVehicleClass(SUMOVehicleClass vclass) const
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()...
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
#define CUT_IN_LEFT_SPEED_THRESHOLD
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key ...
The action is due to a TraCI request.
The link is a 180 degree turn (left-hand network)
virtual double followSpeedTransient(double duration, const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle's follow speed that avoids a collision for the given amount of time...
#define HELP_DECEL_FACTOR
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
double mySpeedGainProbabilityRight
a value for tracking the probability that a change to the right is beneficial
#define LATGAP_SPEED_THRESHOLD2
static bool gSemiImplicitEulerUpdate
double myCommittedSpeed
the speed when committing to a change maneuver
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
bool ignoreOverlap() const
bool myDontBrake
flag to prevent speed adaptation by slowing down
#define LATGAP_SPEED_THRESHOLD
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
double getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0) ...
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
virtual double getArrivalPos() const
Returns this vehicle's desired arrivalPos for its current route (may change on reroute) ...
double getSpeed() const
Returns the vehicle's current speed.
The vehicle is blocked by right leader.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right ...
std::map< int, int > myCanceledStates
double getLatDist() const
public emergency vehicles
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 is a wrapper a...
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.
The vehicle is blocked by right follower.
int computeSublaneShift(const MSEdge *prevEdge, const MSEdge *curEdge)
compute shift so that prevSublane + shift = newSublane
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) ...
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
void updateExpectedSublaneSpeeds(const MSLeaderDistanceInfo &ahead, int sublaneOffset, int laneIndex)
update expected speeds for each sublane of the current edge
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
void updateGaps(const MSLeaderDistanceInfo &others, double foeOffset, double oldCenter, double gapFactor, double &surplusGapRight, double &surplusGapLeft, bool saveMinGap=false, double netOverlap=0, double latDist=0, std::vector< CLeaderDist > *collectBlockers=0)
check remaining lateral gaps for the given foe vehicles and optionally update minimum lateral gaps ...
The link has no direction (is a dead end link)
#define SPEED_GAIN_MIN_SECONDS
bool amBlockingFollowerPlusNB()
double getWidth() const
Returns the edges's width (sum over all lanes)