39 #define MAGIC_OFFSET 1.
40 #define LOOK_FORWARD 10.
44 #define LCA_RIGHT_IMPATIENCE -1.
45 #define CUT_IN_LEFT_SPEED_THRESHOLD 27.
46 #define MAX_ONRAMP_LENGTH 200.
48 #define LOOK_AHEAD_MIN_SPEED 0.0
49 #define LOOK_AHEAD_SPEED_MEMORY 0.9
51 #define HELP_DECEL_FACTOR 1.0
53 #define HELP_OVERTAKE (10.0 / 3.6)
54 #define MIN_FALLBEHIND (7.0 / 3.6)
58 #define KEEP_RIGHT_TIME 5.0
59 #define KEEP_RIGHT_ACCEPTANCE 7.0
61 #define RELGAIN_NORMALIZATION_MIN_SPEED 10.0
63 #define TURN_LANE_DIST 200.0
64 #define GAIN_PERCEPTION_THRESHOLD 0.05
66 #define SPEED_GAIN_MIN_SECONDS 20.0
68 #define ARRIVALPOS_LAT_THRESHOLD 100.0
71 #define LATGAP_SPEED_THRESHOLD (50 / 3.6)
74 #define LATGAP_SPEED_THRESHOLD2 (50 / 3.6)
77 #define SPEEDGAIN_DECAY_FACTOR 0.5
79 #define SPEEDGAIN_MEMORY_FACTOR 0.5
105 #define DEBUG_COND (myVehicle.isSelected())
117 mySpeedGainProbabilityRight(0),
118 mySpeedGainProbabilityLeft(0),
119 myKeepRightProbability(0),
120 myLeadingBlockerLength(0),
124 myCanChangeFully(true),
125 mySafeLatDistRight(0),
126 mySafeLatDistLeft(0),
135 MAX2(NUMERICAL_EPS, v.getVehicleType().getMinGapLat())) /
136 MAX2(NUMERICAL_EPS, v.getVehicleType().getMinGapLat())))),
139 myMinImpatience(myImpatience),
183 const std::vector<MSVehicle::LaneQ>& preb,
186 double& latDist,
double& maneuverDist,
int& blocked) {
189 const std::string changeType = laneOffset == -1 ?
"right" : (laneOffset == 1 ?
"left" :
"current");
191 #ifdef DEBUG_MANEUVER
201 <<
" considerChangeTo=" << changeType
208 leaders, followers, blockers,
209 neighLeaders, neighFollowers, neighBlockers,
211 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
213 result =
keepLatGap(result, leaders, followers, blockers,
214 neighLeaders, neighFollowers, neighBlockers,
215 neighLane, laneOffset, latDist, maneuverDist, blocked);
217 result |=
getLCA(result, latDist);
219 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE)
220 double latDistTmp = latDist;
223 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE)
225 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" maneuverDist=" << maneuverDist <<
" latDist=" << latDistTmp <<
" mySpeedPrev=" <<
mySpeedLat <<
" speedLat=" <<
DIST2SPEED(latDist) <<
" latDist2=" << latDist <<
"\n";
232 <<
" wantsChangeTo=" << changeType
233 <<
" latDist=" << latDist
234 <<
" maneuverDist=" << maneuverDist
242 <<
" wantsNoChangeTo=" << changeType
299 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
300 #ifdef DEBUG_PATCHSPEED
302 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
309 <<
" wanted=" << wanted
328 double nVSafe = wanted;
334 #ifdef DEBUG_PATCHSPEED
344 #ifdef DEBUG_PATCHSPEED
346 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe + NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
349 nVSafe =
MAX2(min, safe);
357 if (v >= min && v <= max) {
358 nVSafe =
MIN2(v * coopWeight + (1 - coopWeight) * wanted, nVSafe);
360 #ifdef DEBUG_PATCHSPEED
362 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" got accel=" << (*i) <<
" nVSafe=" << nVSafe <<
"\n";
366 #ifdef DEBUG_PATCHSPEED
369 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
373 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
381 #ifdef DEBUG_PATCHSPEED
394 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
399 return (max + wanted) / 2.0;
403 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
408 return (min + wanted) / 2.0;
411 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
416 return (max + wanted) / 2.0;
457 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
462 return (max + wanted) / 2.0;
466 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
486 if (pinfo->first >= 0) {
495 <<
" informedBy=" << sender->
getID()
496 <<
" info=" << pinfo->second
497 <<
" vSafe=" << pinfo->first
510 assert(cld.first != 0);
519 double remainingSeconds) {
525 plannedSpeed =
MIN2(plannedSpeed, v);
530 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
537 if (
gDebugFlag2) std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
541 const double dv = plannedSpeed - nv->
getSpeed();
542 const double overtakeDist = (neighLead.second
548 if (dv < NUMERICAL_EPS
554 || dv * remainingSeconds < overtakeDist) {
569 <<
" cannot overtake leader nv=" << nv->
getID()
571 <<
" remainingSeconds=" << remainingSeconds
572 <<
" targetSpeed=" << targetSpeed
573 <<
" nextSpeed=" << nextSpeed
584 <<
" cannot overtake fast leader nv=" << nv->
getID()
586 <<
" remainingSeconds=" << remainingSeconds
587 <<
" targetSpeed=" << targetSpeed
598 <<
" wants to overtake leader nv=" << nv->
getID()
600 <<
" remainingSeconds=" << remainingSeconds
601 <<
" currentGap=" << neighLead.second
603 <<
" overtakeDist=" << overtakeDist
613 }
else if (neighLead.first != 0) {
616 double dv, nextNVSpeed;
636 std::cout <<
" not blocked by leader nv=" << nv->
getID()
638 <<
" gap=" << neighLead.second
639 <<
" nextGap=" << neighLead.second - dv
641 <<
" targetSpeed=" << targetSpeed
645 return MIN2(targetSpeed, plannedSpeed);
657 double remainingSeconds,
658 double plannedSpeed) {
662 if (
gDebugFlag2) std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
669 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
672 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
691 const double neighNewSpeed1s =
MAX2(0., nv->
getSpeed() - helpDecel);
692 const double dv = plannedSpeed - neighNewSpeed1s;
694 const double decelGap = neighFollow.second + dv;
700 <<
" egoNV=" << plannedSpeed
701 <<
" nvNewSpeed=" << neighNewSpeed
702 <<
" nvNewSpeed1s=" << neighNewSpeed1s
703 <<
" deltaGap=" << dv
704 <<
" decelGap=" << decelGap
705 <<
" secGap=" << secureGap
709 if (decelGap > 0 && decelGap >= secureGap) {
724 std::cout <<
" wants to cut in before nv=" << nv->
getID()
725 <<
" vsafe1=" << vsafe1
726 <<
" vsafe=" << vsafe
731 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap + POSITION_EPS)) {
736 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
744 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
760 std::cout <<
" wants right follower to slow down a bit\n";
766 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
775 const double overtakeDist = (neighFollow.second
781 const double needDV = overtakeDist / remainingSeconds;
789 <<
" wants to be overtaken by=" << nv->
getID()
790 <<
" overtakeDist=" << overtakeDist
792 <<
" vhelp=" << vhelp
793 <<
" needDV=" << needDV
799 }
else if (neighFollow.first != 0) {
809 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
817 const std::vector<CLeaderDist>& blockers,
818 double remainingSeconds) {
830 plannedSpeed =
MIN2(plannedSpeed, safe);
832 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
833 plannedSpeed =
MIN2(plannedSpeed,
informLeader(blocked, dir, *it, remainingSeconds));
841 const std::vector<CLeaderDist>& blockers,
842 double remainingSeconds,
843 double plannedSpeed) {
845 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
846 informFollower(blocked, dir, *it, remainingSeconds, plannedSpeed);
871 const double halfWidth =
getWidth() * 0.5;
881 std::vector<double> newExpectedSpeeds;
890 const std::vector<MSLane*>& lanes = currEdge->
getLanes();
891 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
893 for (
int i = 0; i < subLanes; ++i) {
894 newExpectedSpeeds.push_back((*it_lane)->getVehicleMaxSpeed(&
myVehicle));
902 if (subLaneShift < std::numeric_limits<int>::max()) {
904 const int newI = i + subLaneShift;
905 if (newI > 0 && newI < (
int)newExpectedSpeeds.size()) {
941 for (
const MSLink*
const link : lane->getLinkCont()) {
942 if (&link->getLane()->getEdge() == curEdge) {
944 const MSLane* target = link->getLane();
945 const std::vector<MSLane*>& lanes2 = curEdge->
getLanes();
946 for (std::vector<MSLane*>::const_iterator it_lane2 = lanes2.begin(); it_lane2 != lanes2.end(); ++it_lane2) {
947 const MSLane* lane2 = *it_lane2;
948 if (lane2 == target) {
949 return prevShift + curShift;
960 return std::numeric_limits<int>::max();
990 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE)
1009 const std::vector<MSVehicle::LaneQ>& preb,
1012 double& latDist,
double& maneuverDist,
int& blocked) {
1017 int bestLaneOffset = 0;
1018 double currentDist = 0;
1019 double neighDist = 0;
1028 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1029 for (
int p = 0; p < (int) preb.size(); ++p) {
1030 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1031 assert(p + prebOffset < (
int)preb.size());
1033 neigh = preb[p + prebOffset];
1034 currentDist = curr.
length;
1035 neighDist = neigh.
length;
1038 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
1039 #ifdef DEBUG_WANTSCHANGE
1043 <<
" bestLaneOffsetOld=" << bestLaneOffset
1044 <<
" bestLaneOffsetNew=" << laneOffset
1048 bestLaneOffset = laneOffset;
1050 best = preb[p + bestLaneOffset];
1055 double driveToNextStop = -std::numeric_limits<double>::max();
1064 #ifdef DEBUG_WANTS_CHANGE
1069 <<
" stopPos=" << stopPos
1070 <<
" currentDist=" << currentDist
1071 <<
" neighDist=" << neighDist
1075 currentDist =
MAX2(currentDist, stopPos);
1076 neighDist =
MAX2(neighDist, stopPos);
1079 const bool right = (laneOffset == -1);
1080 const bool left = (laneOffset == 1);
1083 const bool changeToBest = (right && bestLaneOffset < 0) || (left && bestLaneOffset > 0) || (laneOffset == 0 && bestLaneOffset == 0);
1109 #ifdef DEBUG_WANTSCHANGE
1116 <<
"\n leaders=" << leaders.
toString()
1117 <<
"\n followers=" << followers.
toString()
1118 <<
"\n blockers=" << blockers.
toString()
1119 <<
"\n neighLeaders=" << neighLeaders.
toString()
1120 <<
"\n neighFollowers=" << neighFollowers.
toString()
1121 <<
"\n neighBlockers=" << neighBlockers.
toString()
1122 <<
"\n changeToBest=" << changeToBest
1123 <<
" latLaneDist=" << latLaneDist
1131 if (lastBlocked != firstBlocked) {
1192 currentDist += roundaboutBonus;
1193 neighDist += roundaboutBonus;
1195 if (laneOffset != 0) {
1212 if ((ret &
LCA_STAY) != 0 && latDist == 0) {
1222 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;
1245 maneuverDist = latDist;
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
1282 if (roundaboutBonus > 0) {
1284 #ifdef DEBUG_WANTS_CHANGE
1288 <<
" roundaboutBonus=" << roundaboutBonus
1299 latDist = latLaneDist;
1300 maneuverDist = latLaneDist;
1301 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1302 leaders, followers, blockers,
1303 neighLeaders, neighFollowers, neighBlockers);
1323 const double inconvenience = (latLaneDist < 0
1337 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1340 #ifdef DEBUG_COOPERATE
1347 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1357 maneuverDist = latDist;
1358 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1359 leaders, followers, blockers,
1360 neighLeaders, neighFollowers, neighBlockers);
1386 const double vehWidth =
getWidth();
1388 const double leftVehSide = rightVehSide + vehWidth;
1390 double defaultNextSpeed = std::numeric_limits<double>::max();
1392 int leftmostOnEdge = (int)sublaneSides.size() - 1;
1393 while (leftmostOnEdge > 0 && sublaneSides[leftmostOnEdge] > leftVehSide) {
1396 int rightmostOnEdge = leftmostOnEdge;
1397 while (rightmostOnEdge > 0 && sublaneSides[rightmostOnEdge] > rightVehSide + NUMERICAL_EPS) {
1399 #ifdef DEBUG_WANTSCHANGE
1401 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1402 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1408 #ifdef DEBUG_WANTSCHANGE
1410 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1411 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1414 double maxGain = -std::numeric_limits<double>::max();
1415 double maxGainRight = -std::numeric_limits<double>::max();
1416 double maxGainLeft = -std::numeric_limits<double>::max();
1417 double latDistNice = std::numeric_limits<double>::max();
1420 const double leftMax =
MAX2(
1424 assert(leftMax <= edge.
getWidth());
1425 int sublaneCompact =
MAX2(iMin, rightmostOnEdge - 1);
1427 #ifdef DEBUG_WANTSCHANGE
1429 <<
" checking sublanes rightmostOnEdge=" << rightmostOnEdge
1430 <<
" leftmostOnEdge=" << leftmostOnEdge
1432 <<
" leftMax=" << leftMax
1433 <<
" sublaneCompact=" << sublaneCompact
1440 const double maxLatDist = leftMax - leftVehSide;
1441 const double minLatDist = rightMin - rightVehSide;
1442 const int iStart = laneOffset == 0 ? iMin : 0;
1443 const double rightEnd = laneOffset == 0 ? leftMax : edge.
getWidth();
1444 for (
int i = iStart; i < (int)sublaneSides.size(); ++i) {
1445 if (sublaneSides[i] + vehWidth < rightEnd) {
1451 while (vMin > 0 && j < (
int)sublaneSides.size() && sublaneSides[j] < sublaneSides[i] + vehWidth) {
1457 if (laneOffset != 0 &&
overlap(sublaneSides[i], sublaneSides[i] + vehWidth, laneBoundary, laneBoundary)) {
1461 const double currentLatDist =
MIN2(
MAX2(sublaneSides[i] - rightVehSide, minLatDist), maxLatDist);
1463 if (relativeGain > maxGain) {
1464 maxGain = relativeGain;
1467 latDist = currentLatDist;
1468 #ifdef DEBUG_WANTSCHANGE
1470 std::cout <<
" i=" << i <<
" newLatDist=" << latDist <<
" relGain=" << relativeGain <<
"\n";
1476 if (currentLatDist > 0
1480 && maxGain - relativeGain < NUMERICAL_EPS) {
1481 latDist = currentLatDist;
1484 #ifdef DEBUG_WANTSCHANGE
1486 std::cout <<
" i=" << i <<
" rightmostOnEdge=" << rightmostOnEdge <<
" vMin=" << vMin <<
" relGain=" << relativeGain <<
" sublaneCompact=" << sublaneCompact <<
" curLatDist=" << currentLatDist <<
"\n";
1490 maxGainRight =
MAX2(maxGainRight, relativeGain);
1492 maxGainLeft =
MAX2(maxGainLeft, relativeGain);
1494 const double subAlignDist = sublaneSides[i] - rightVehSide;
1495 if (fabs(subAlignDist) < fabs(latDistNice)) {
1496 latDistNice = subAlignDist;
1497 #ifdef DEBUG_WANTSCHANGE
1499 <<
" nicest sublane=" << i
1500 <<
" side=" << sublaneSides[i]
1501 <<
" rightSide=" << rightVehSide
1502 <<
" latDistNice=" << latDistNice
1503 <<
" maxGainR=" << maxGainRight
1504 <<
" maxGainL=" << maxGainLeft
1511 if (maxGainRight != -std::numeric_limits<double>::max()) {
1512 #ifdef DEBUG_WANTSCHANGE
1518 #ifdef DEBUG_WANTSCHANGE
1524 if (maxGainLeft != -std::numeric_limits<double>::max()) {
1525 #ifdef DEBUG_WANTSCHANGE
1531 #ifdef DEBUG_WANTSCHANGE
1538 if ((fabs(maxGainRight) < NUMERICAL_EPS || maxGainRight == -std::numeric_limits<double>::max())
1539 && (right || (alternatives &
LCA_RIGHT) == 0)) {
1542 if ((fabs(maxGainLeft) < NUMERICAL_EPS || maxGainLeft == -std::numeric_limits<double>::max())
1543 && (left || (alternatives &
LCA_LEFT) == 0)) {
1548 #ifdef DEBUG_WANTSCHANGE
1551 <<
" defaultNextSpeed=" << defaultNextSpeed
1552 <<
" maxGain=" << maxGain
1553 <<
" maxGainRight=" << maxGainRight
1554 <<
" maxGainLeft=" << maxGainLeft
1555 <<
" latDist=" << latDist
1556 <<
" latDistNice=" << latDistNice
1557 <<
" sublaneCompact=" << sublaneCompact
1573 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1575 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1576 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1578 vMax, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1579 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1584 #ifdef DEBUG_WANTSCHANGE
1587 <<
" considering keepRight:"
1589 <<
" neighDist=" << neighDist
1591 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1593 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1594 <<
" acceptanceTime=" << acceptanceTime
1595 <<
" fullSpeedGap=" << fullSpeedGap
1596 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1597 <<
" dProb=" << deltaProb
1608 latDist = latLaneDist;
1609 maneuverDist = latLaneDist;
1610 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1611 leaders, followers, blockers,
1612 neighLeaders, neighFollowers, neighBlockers);
1620 #ifdef DEBUG_WANTSCHANGE
1625 <<
" neighDist=" << neighDist
1628 <<
" latDist=" << latDist
1637 int blockedFully = 0;
1638 maneuverDist = latDist;
1639 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1640 leaders, followers, blockers,
1641 neighLeaders, neighFollowers, neighBlockers,
1642 nullptr,
nullptr,
false, 0, &blockedFully);
1655 #ifdef DEBUG_WANTSCHANGE
1660 <<
" latDist=" << latDist
1661 <<
" neighDist=" << neighDist
1664 <<
" stayInLane=" << stayInLane
1675 int blockedFully = 0;
1676 maneuverDist = latDist;
1677 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1678 leaders, followers, blockers,
1679 neighLeaders, neighFollowers, neighBlockers,
1680 nullptr,
nullptr,
false, 0, &blockedFully);
1690 double latDistSublane = 0.;
1692 const double halfVehWidth =
getWidth() * 0.5;
1695 && bestLaneOffset == 0
1715 #ifdef DEBUG_WANTSCHANGE
1729 switch (turnInfo.second) {
1749 latDistSublane = -halfLaneWidth + halfVehWidth -
getPosLat();
1752 latDistSublane = halfLaneWidth - halfVehWidth -
getPosLat();
1758 latDistSublane = latDistNice;
1761 latDistSublane = sublaneSides[sublaneCompact] - rightVehSide;
1770 latDistSublane * latDist > 0) {
1772 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) || defined(DEBUG_MANEUVER)
1777 <<
" latDist=" << latDist
1778 <<
" latDistSublane=" << latDistSublane
1779 <<
" relGainSublane=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed)
1780 <<
" maneuverDist=" << maneuverDist
1792 #if defined(DEBUG_WANTSCHANGE)
1794 <<
" speedGain=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed) <<
")\n";
1802 #if defined(DEBUG_WANTSCHANGE)
1804 std::cout <<
" aborting sublane change due to prior maneuver\n";
1809 latDist = latDistSublane;
1814 #ifdef DEBUG_WANTSCHANGE
1817 <<
" latDist=" << latDist
1825 #ifdef DEBUG_WANTSCHANGE
1831 maneuverDist = latDist;
1832 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1833 leaders, followers, blockers,
1834 neighLeaders, neighFollowers, neighBlockers);
1863 #ifdef DEBUG_WANTSCHANGE
1880 if ((*blocked) !=
nullptr) {
1882 #ifdef DEBUG_SLOWDOWN
1891 if (gap > POSITION_EPS) {
1905 (gap - POSITION_EPS), (*blocked)->getSpeed(),
1906 (*blocked)->getCarFollowModel().getMaxDecel()));
1917 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1933 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1941 #ifdef DEBUG_SAVE_BLOCKER_LENGTH
1958 <<
"vSafe=" << vSafe <<
" -> accel=" << accel <<
"\n";
1968 const MSLane* lane = lanes[laneIndex];
1970 assert(preb.size() == lanes.size());
1972 for (
int sublane = 0; sublane < (int)ahead.
numSublanes(); ++sublane) {
1973 const int edgeSublane = sublane + sublaneOffset;
1981 const MSVehicle* leader = ahead[sublane].first;
1982 const double gap = ahead[sublane].second;
1984 if (leader ==
nullptr) {
1994 #ifdef DEBUG_EXPECTED_SLSPEED
1996 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" updateExpectedSublaneSpeeds edgeSublane=" << edgeSublane <<
" leader=" << leader->
getID() <<
" gap=" << gap <<
" vSafe=" << vSafe <<
"\n";
1999 const double deltaV = vMax - leader->
getSpeed();
2004 const double gapClosingTime = gap / deltaV;
2005 const double vSafe2 = (gapClosingTime * vSafe + (foreCastTime - gapClosingTime) * leader->
getSpeed()) / foreCastTime;
2006 #ifdef DEBUG_EXPECTED_SLSPEED
2008 std::cout <<
" foreCastTime=" << foreCastTime <<
" gapClosingTime=" << gapClosingTime <<
" extrapolated vSafe=" << vSafe <<
"\n";
2018 double foeRight, foeLeft;
2022 if (leader.first != 0) {
2025 vSafe =
MIN2(vSafe, vSafePed);
2028 vSafe =
MIN2(vMax, vSafe);
2042 double result = std::numeric_limits<double>::max();
2044 const double vehWidth =
getWidth();
2046 const double leftVehSide = rightVehSide + vehWidth;
2047 for (
int i = 0; i < (int)sublaneSides.size(); ++i) {
2049 if (
overlap(rightVehSide, leftVehSide, sublaneSides[i], leftSide)) {
2054 return result - defaultNextSpeed;
2061 double maxLength = -1;
2063 if (ldi[i].first != 0) {
2064 const double length = ldi[i].first->getVehicleType().getLength();
2065 if (length > maxLength) {
2078 double minSpeed = std::numeric_limits<double>::max();
2080 if (ldi[i].first != 0) {
2081 const double speed = ldi[i].first->getSpeed();
2082 if (speed < minSpeed) {
2100 std::vector<CLeaderDist>* collectLeadBlockers,
2101 std::vector<CLeaderDist>* collectFollowBlockers,
2102 bool keepLatGapManeuver,
2104 int* retBlockedFully) {
2107 latDist =
MAX2(
MIN2(latDist, maxDist), -maxDist);
2115 if (laneOffset != 0) {
2126 if (laneOffset != 0) {
2130 #ifdef DEBUG_BLOCKING
2142 }
else if (!forcedTraCIChange) {
2148 }
else if (!forcedTraCIChange) {
2154 #ifdef DEBUG_BLOCKING
2156 std::cout <<
" checkBlocking fully=" <<
myCanChangeFully <<
" latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
"\n";
2170 if (laneOffset != 0) {
2179 int blockedFully = 0;
2184 if (laneOffset != 0) {
2192 if (retBlockedFully !=
nullptr) {
2193 *retBlockedFully = blockedFully;
2200 blocked |= blockedFully;
2205 if (collectFollowBlockers !=
nullptr && collectLeadBlockers !=
nullptr) {
2207 for (std::vector<CLeaderDist>::const_iterator it2 = collectLeadBlockers->begin(); it2 != collectLeadBlockers->end(); ++it2) {
2208 for (std::vector<CLeaderDist>::iterator it = collectFollowBlockers->begin(); it != collectFollowBlockers->end();) {
2209 if ((*it2).first == (*it).first) {
2210 #ifdef DEBUG_BLOCKING
2212 std::cout <<
" removed follower " << (*it).first->getID() <<
" because it is already a leader\n";
2215 it = collectFollowBlockers->erase(it);
2229 double latDist,
double foeOffset,
bool leaders,
LaneChangeAction blockType,
2230 double& safeLatGapRight,
double& safeLatGapLeft,
2231 std::vector<CLeaderDist>* collectBlockers)
const {
2233 const double vehWidth =
getWidth();
2235 const double leftVehSide = rightVehSide + vehWidth;
2236 const double rightVehSideDest = rightVehSide + latDist;
2237 const double leftVehSideDest = leftVehSide + latDist;
2238 const double rightNoOverlap =
MIN2(rightVehSideDest, rightVehSide);
2239 const double leftNoOverlap =
MAX2(leftVehSideDest, leftVehSide);
2240 #ifdef DEBUG_BLOCKING
2242 std::cout <<
" checkBlockingVehicles"
2243 <<
" latDist=" << latDist
2244 <<
" foeOffset=" << foeOffset
2245 <<
" vehRight=" << rightVehSide
2246 <<
" vehLeft=" << leftVehSide
2247 <<
" rightNoOverlap=" << rightNoOverlap
2248 <<
" leftNoOverlap=" << leftNoOverlap
2249 <<
" destRight=" << rightVehSideDest
2250 <<
" destLeft=" << leftVehSideDest
2251 <<
" leaders=" << leaders
2257 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2259 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2260 const MSVehicle* leader = vehDist.first;
2263 std::swap(leader, follower);
2266 double foeRight, foeLeft;
2268 const bool overlapBefore =
overlap(rightVehSide, leftVehSide, foeRight, foeLeft);
2269 const bool overlapDest =
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft);
2270 const bool overlapAny =
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft);
2271 #ifdef DEBUG_BLOCKING
2273 std::cout <<
" foe=" << vehDist.first->getID()
2274 <<
" gap=" << vehDist.second
2276 <<
" foeRight=" << foeRight
2277 <<
" foeLeft=" << foeLeft
2278 <<
" overlapBefore=" << overlapBefore
2279 <<
" overlap=" << overlapAny
2280 <<
" overlapDest=" << overlapDest
2285 if (vehDist.second < 0) {
2286 if (overlapBefore && !overlapDest) {
2287 #ifdef DEBUG_BLOCKING
2289 std::cout <<
" ignoring current overlap to come clear\n";
2293 #ifdef DEBUG_BLOCKING
2299 if (collectBlockers ==
nullptr) {
2302 collectBlockers->push_back(vehDist);
2318 const double expectedGap =
MSCFModel::gapExtrapolation(timeTillAction, vehDist.second, leader->
getSpeed(), follower->
getSpeed(), leaderAccel, followerAccel, std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
2321 const double followerExpectedSpeed = follower->
getSpeed() + timeTillAction * followerAccel;
2322 const double leaderExpectedSpeed =
MAX2(0., leader->
getSpeed() + timeTillAction * leaderAccel);
2325 #if defined(DEBUG_ACTIONSTEPS) && defined(DEBUG_BLOCKING)
2327 std::cout <<
" timeTillAction=" << timeTillAction
2328 <<
" followerAccel=" << followerAccel
2329 <<
" followerExpectedSpeed=" << followerExpectedSpeed
2330 <<
" leaderAccel=" << leaderAccel
2331 <<
" leaderExpectedSpeed=" << leaderExpectedSpeed
2332 <<
"\n gap=" << vehDist.second
2333 <<
" gapChange=" << (expectedGap - vehDist.second)
2334 <<
" expectedGap=" << expectedGap
2335 <<
" expectedSecureGap=" << expectedSecureGap
2336 <<
" safeLatGapLeft=" << safeLatGapLeft
2337 <<
" safeLatGapRight=" << safeLatGapRight
2344 if (expectedGap < secureGap2) {
2346 if (foeRight > leftVehSide) {
2347 safeLatGapLeft =
MIN2(safeLatGapLeft, foeRight - leftVehSide);
2348 }
else if (foeLeft < rightVehSide) {
2349 safeLatGapRight =
MIN2(safeLatGapRight, rightVehSide - foeLeft);
2352 #ifdef DEBUG_BLOCKING
2354 std::cout <<
" blocked by " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2355 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor()
2356 <<
" safeLatGapLeft=" << safeLatGapLeft <<
" safeLatGapRight=" << safeLatGapRight
2360 result |= blockType;
2361 if (collectBlockers ==
nullptr) {
2364 #ifdef DEBUG_BLOCKING
2365 }
else if (
gDebugFlag2 && expectedGap < expectedSecureGap) {
2366 std::cout <<
" ignore blocker " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2367 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor() <<
"\n";
2370 if (collectBlockers !=
nullptr) {
2373 collectBlockers->push_back(vehDist);
2390 const double leftVehSide = rightVehSide + vehWidth;
2391 #ifdef DEBUG_BLOCKING
2393 std::cout <<
" updateCFRelated foeOffset=" << foeOffset <<
" vehicles=" << vehicles.
toString() <<
"\n";
2396 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2398 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2399 double foeRight, foeLeft;
2401 if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft) && (vehDist.second >= 0
2407 && -vehDist.second < vehDist.first->getVehicleType().getMinGap()
2410 #ifdef DEBUG_BLOCKING
2412 std::cout <<
" ignoring cfrelated foe=" << vehDist.first->getID() <<
" gap=" << vehDist.second
2414 <<
" foeOffset=" << foeOffset
2415 <<
" egoR=" << rightVehSide <<
" egoL=" << leftVehSide
2416 <<
" iR=" << foeRight <<
" iL=" << foeLeft
2431 assert(right <= left);
2432 assert(right2 <= left2);
2433 return left2 >= right + NUMERICAL_EPS && left >= right2 + NUMERICAL_EPS;
2454 return changeReason;
2461 if (sd1.
state == 0) {
2463 }
else if (sd2.
state == 0) {
2473 #ifdef DEBUG_WANTSCHANGE
2479 <<
" dir1=" << sd1.
dir
2483 <<
" dir2=" << sd2.
dir
2491 if (reason1 < reason2) {
2493 return (!can1 && can2 && sd1.
sameDirection(sd2)) ? sd2 : sd1;
2495 }
else if (reason1 > reason2) {
2497 return (!can2 && can1 && sd1.
sameDirection(sd2)) ? sd1 : sd2;
2505 }
else if (sd2.
dir == 0) {
2510 assert(sd1.
dir == -1);
2511 assert(sd2.
dir == 1);
2514 }
else if (sd2.
latDist >= 0) {
2522 return can1 ? sd1 : sd2;
2545 const std::vector<MSVehicle::LaneQ>& preb,
2554 double roundaboutBonus,
2558 const bool right = (laneOffset == -1);
2559 const bool left = (laneOffset == 1);
2571 #ifdef DEBUG_STRATEGIC_CHANGE
2576 <<
" laDist=" << laDist
2577 <<
" currentDist=" << currentDist
2578 <<
" usableDist=" << usableDist
2579 <<
" bestLaneOffset=" << bestLaneOffset
2580 <<
" best.length=" << best.
length
2581 <<
" maxJam=" << maxJam
2582 <<
" neighLeftPlace=" << neighLeftPlace
2588 if (laneOffset != 0 && changeToBest && bestLaneOffset == curr.
bestLaneOffset
2591 latDist = latLaneDist;
2608 #ifdef DEBUG_STRATEGIC_CHANGE
2611 <<
" avoid overtaking on the right nv=" << nv->
getID()
2621 if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
2628 #ifdef DEBUG_STRATEGIC_CHANGE
2630 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
2636 && bestLaneOffset == 0
2639 && roundaboutBonus == 0
2645 #ifdef DEBUG_STRATEGIC_CHANGE
2647 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
2652 && bestLaneOffset == 0
2658 #ifdef DEBUG_STRATEGIC_CHANGE
2660 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
2674 MSLane* shadowPrev =
nullptr;
2676 if (*it ==
nullptr) {
2680 if (shadow ==
nullptr || currentShadowDist >= requiredDist) {
2683 if (shadowPrev !=
nullptr) {
2686 currentShadowDist += shadow->
getLength();
2687 shadowPrev = shadow;
2688 #ifdef DEBUG_STRATEGIC_CHANGE
2690 std::cout <<
" shadow=" << shadow->
getID() <<
" currentShadowDist=" << currentShadowDist <<
"\n";
2694 #ifdef DEBUG_STRATEGIC_CHANGE
2699 if (currentShadowDist < requiredDist && currentShadowDist < usableDist) {
2702 #ifdef DEBUG_STRATEGIC_CHANGE
2704 std::cout <<
" must change for shadowLane end latDist=" << latDist <<
" myLeftSpace=" <<
myLeftSpace <<
"\n";
2712 #if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI)
2724 }
else if (((retTraCI &
LCA_RIGHT) != 0 && laneOffset < 0)
2725 || ((retTraCI &
LCA_LEFT) != 0 && laneOffset > 0)) {
2727 latDist = latLaneDist;
2730 #if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI)
2732 std::cout <<
" reqAfterInfluence=" << ret <<
" ret=" << ret <<
"\n";
2756 double& maneuverDist,
2792 const bool stayInLane = laneOffset == 0 || ((state &
LCA_STRATEGIC) != 0 && (state &
LCA_STAY) != 0);
2793 const double oldLatDist = latDist;
2794 const double oldManeuverDist = maneuverDist;
2797 const double halfWidth =
getWidth() * 0.5;
2803 double surplusGapRight = oldCenter - halfWidth;
2805 #ifdef DEBUG_KEEP_LATGAP
2807 std::cout <<
"\n " <<
SIMTIME <<
" keepLatGap() laneOffset=" << laneOffset
2808 <<
" latDist=" << latDist
2809 <<
" maneuverDist=" << maneuverDist
2812 <<
" gapFactor=" << gapFactor
2813 <<
" stayInLane=" << stayInLane <<
"\n"
2814 <<
" stayInEdge: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2818 if (surplusGapLeft < 0 || surplusGapRight < 0) {
2828 if (laneOffset != 0) {
2833 #ifdef DEBUG_KEEP_LATGAP
2835 std::cout <<
" minGapLat: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n"
2844 if (stayInLane || laneOffset == 1) {
2850 if (stayInLane || laneOffset == -1) {
2856 #ifdef DEBUG_KEEP_LATGAP
2858 std::cout <<
" stayInLane: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2862 if (surplusGapRight + surplusGapLeft < 0) {
2867 const double equalDeficit = 0.5 * (surplusGapLeft + surplusGapRight);
2868 if (surplusGapRight < surplusGapLeft) {
2870 const double delta =
MIN2(equalDeficit - surplusGapRight, physicalGapLeft);
2872 maneuverDist = delta;
2873 #ifdef DEBUG_KEEP_LATGAP
2875 std::cout <<
" insufficient latSpace, move left: delta=" << delta <<
"\n";
2880 const double delta =
MIN2(equalDeficit - surplusGapLeft, physicalGapRight);
2882 maneuverDist = -delta;
2883 #ifdef DEBUG_KEEP_LATGAP
2885 std::cout <<
" insufficient latSpace, move right: delta=" << delta <<
"\n";
2891 latDist =
MAX2(
MIN2(latDist, surplusGapLeft), -surplusGapRight);
2892 maneuverDist =
MAX2(
MIN2(maneuverDist, surplusGapLeft), -surplusGapRight);
2893 if ((state &
LCA_KEEPRIGHT) != 0 && maneuverDist != oldManeuverDist) {
2895 latDist = oldLatDist;
2896 maneuverDist = oldManeuverDist;
2898 #ifdef DEBUG_KEEP_LATGAP
2900 std::cout <<
" adapted latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
" (old=" << oldLatDist <<
")\n";
2910 #ifdef DEBUG_KEEP_LATGAP
2912 std::cout <<
" traci influenced latDist=" << latDist <<
"\n";
2918 const bool traciChange = (state &
LCA_TRACI) != 0;
2919 if (nonSublaneChange && !traciChange) {
2921 #ifdef DEBUG_KEEP_LATGAP
2923 std::cout <<
" wanted changeToLeft oldLatDist=" << oldLatDist <<
", blocked latGap changeToRight\n";
2926 latDist = oldLatDist;
2929 #ifdef DEBUG_KEEP_LATGAP
2931 std::cout <<
" wanted changeToRight oldLatDist=" << oldLatDist <<
", blocked latGap changeToLeft\n";
2934 latDist = oldLatDist;
2944 #ifdef DEBUG_KEEP_LATGAP
2946 std::cout <<
" latDistUpdated=" << latDist <<
" oldLatDist=" << oldLatDist <<
"\n";
2949 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset, leaders, followers, blockers, neighLeaders, neighFollowers, neighBlockers,
nullptr,
nullptr, nonSublaneChange);
2963 #if defined(DEBUG_KEEP_LATGAP) || defined(DEBUG_STATE)
2965 std::cout <<
" latDist2=" << latDist
2979 double& surplusGapRight,
double& surplusGapLeft,
2980 bool saveMinGap,
double netOverlap,
2982 std::vector<CLeaderDist>* collectBlockers) {
2984 const double halfWidth =
getWidth() * 0.5 + NUMERICAL_EPS;
2987 if (others[i].first != 0 && others[i].second <= 0
2989 && (netOverlap == 0 || others[i].second + others[i].first->getVehicleType().getMinGap() < netOverlap)) {
2993 double foeRight, foeLeft;
2995 const double foeCenter = foeRight + 0.5 * res;
2996 const double gap =
MIN2(fabs(foeRight - oldCenter), fabs(foeLeft - oldCenter)) - halfWidth;
2999 const double currentMinGap = desiredMinGap * gapFactor;
3010 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP)
3012 std::cout <<
" updateGaps"
3014 <<
" foe=" << foe->
getID()
3015 <<
" foeRight=" << foeRight
3016 <<
" foeLeft=" << foeLeft
3017 <<
" oldCenter=" << oldCenter
3018 <<
" gap=" << others[i].second
3019 <<
" latgap=" << gap
3020 <<
" currentMinGap=" << currentMinGap
3021 <<
" surplusGapRight=" << surplusGapRight
3022 <<
" surplusGapLeft=" << surplusGapLeft
3030 if (foeCenter < oldCenter) {
3032 surplusGapRight =
MIN3(surplusGapRight, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
3035 surplusGapLeft =
MIN3(surplusGapLeft, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
3038 if (foeCenter < oldCenter) {
3039 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP)
3041 std::cout <<
" new minimum rightGap=" << gap <<
"\n";
3046 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP)
3048 std::cout <<
" new minimum leftGap=" << gap <<
"\n";
3054 if (collectBlockers !=
nullptr) {
3056 if ((foeCenter < oldCenter && latDist < 0 && gap < (desiredMinGap - latDist))
3057 || (foeCenter > oldCenter && latDist > 0 && gap < (desiredMinGap + latDist))) {
3058 collectBlockers->push_back(others[i]);
3075 int currentDirection =
mySpeedLat >= 0 ? 1 : -1;
3076 int directionWish = latDist >= 0 ? 1 : -1;
3080 maxSpeedLat =
MIN2(maxSpeedLat, speedBound);
3083 #ifdef DEBUG_MANEUVER
3087 <<
" computeSpeedLat()"
3088 <<
" currentDirection=" << currentDirection
3089 <<
" directionWish=" << directionWish
3095 if (directionWish == 1) {
3106 double speedAccelSafe = latDist * speedAccel >= 0 ? speedAccel : 0;
3114 if (maneuverDist * latDist > 0) {
3115 maneuverDist = fullLatDist;
3118 #ifdef DEBUG_MANEUVER
3123 <<
" latDist=" << latDist
3124 <<
" maneuverDist=" << maneuverDist
3127 <<
" fullLatDist=" << fullLatDist
3128 <<
" speedAccel=" << speedAccel
3129 <<
" speedDecel=" << speedDecel
3130 <<
" speedDecelSafe=" << speedDecelSafe
3131 <<
" speedBound=" << speedBound
3135 if (speedDecel * speedAccel <= 0 && (
3137 (latDist >= 0 && speedAccel >= speedBound && speedBound >= speedDecel)
3138 || (latDist <= 0 && speedAccel <= speedBound && speedBound <= speedDecel))) {
3140 #ifdef DEBUG_MANEUVER
3142 std::cout <<
" computeSpeedLat a)\n";
3149 #ifdef DEBUG_MANEUVER
3151 std::cout <<
" computeSpeedLat b)\n";
3154 return speedAccelSafe;
3158 if ((fabs(minDistAccel) < fabs(fullLatDist)) || (fabs(minDistAccel - fullLatDist) < NUMERICAL_EPS)) {
3159 #ifdef DEBUG_MANEUVER
3161 std::cout <<
" computeSpeedLat c)\n";
3166 #ifdef DEBUG_MANEUVER
3168 std::cout <<
" minDistAccel=" << minDistAccel <<
"\n";
3173 if ((fabs(minDistCurrent) < fabs(fullLatDist)) || (fabs(minDistCurrent - fullLatDist) < NUMERICAL_EPS)) {
3174 #ifdef DEBUG_MANEUVER
3176 std::cout <<
" computeSpeedLat d)\n";
3183 #ifdef DEBUG_MANEUVER
3185 std::cout <<
" computeSpeedLat e)\n";
3188 return speedDecelSafe;
3197 double maneuverDist) {
3200 double secondsToLeaveLane;
3210 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3226 double nextLeftSpace;
3227 if (nextActionStepSpeed > 0.) {
3242 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3246 <<
" avoidArrivalSpeed=" << avoidArrivalSpeed
3249 <<
"\n nextLeftSpace=" << nextLeftSpace
3250 <<
" nextActionStepSpeed=" << nextActionStepSpeed
3251 <<
" nextActionStepRemainingSeconds=" << secondsToLeaveLane - timeTillActionStep
3261 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3265 <<
" secondsToLeave=" << secondsToLeaveLane
3287 const double vehWidth =
getWidth();
3289 const double leftVehSide = rightVehSide + vehWidth;
3290 const double rightVehSideDest = rightVehSide + latDist;
3291 const double leftVehSideDest = leftVehSide + latDist;
3292 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3294 std::cout <<
" commitFollowSpeed"
3295 <<
" latDist=" << latDist
3296 <<
" foeOffset=" << foeOffset
3297 <<
" vehRight=" << rightVehSide
3298 <<
" vehLeft=" << leftVehSide
3299 <<
" destRight=" << rightVehSideDest
3300 <<
" destLeft=" << leftVehSideDest
3306 if (vehDist.first != 0) {
3307 const MSVehicle* leader = vehDist.first;
3309 double foeRight, foeLeft;
3311 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3313 std::cout <<
" foe=" << vehDist.first->getID()
3314 <<
" gap=" << vehDist.second
3316 <<
" foeRight=" << foeRight
3317 <<
" foeLeft=" << foeLeft
3318 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
3319 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
3323 if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
3327 speed =
MIN2(speed, vSafe);
3328 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3330 std::cout <<
" case1 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3333 }
else if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)) {
3338 speed =
MIN2(speed, vSafe);
3339 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3341 std::cout <<
" case2 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3457 const std::pair<MSVehicle*, double>& leader,
3458 const std::pair<MSVehicle*, double>& neighLead,
3459 const std::pair<MSVehicle*, double>& neighFollow,
3461 const std::vector<MSVehicle::LaneQ>& preb,
3467 #ifdef DEBUG_WANTSCHANGE
3469 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME
3476 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3490 double maneuverDist;
3493 leaders, followers, blockers,
3494 neighLeaders, neighFollowers, neighBlockers,
3496 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
3501 result |=
getLCA(result, latDist);
3503 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE)
3508 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3509 << ((result &
LCA_URGENT) ?
" (urgent)" :
"")
3515 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
#define ARRIVALPOS_LAT_THRESHOLD
#define HELP_DECEL_FACTOR
#define SPEEDGAIN_MEMORY_FACTOR
#define LOOK_AHEAD_MIN_SPEED
#define LCA_RIGHT_IMPATIENCE
#define KEEP_RIGHT_ACCEPTANCE
#define RELGAIN_NORMALIZATION_MIN_SPEED
#define CUT_IN_LEFT_SPEED_THRESHOLD
#define MAX_ONRAMP_LENGTH
#define SPEEDGAIN_DECAY_FACTOR
#define LATGAP_SPEED_THRESHOLD
#define LOOK_AHEAD_SPEED_MEMORY
#define GAIN_PERCEPTION_THRESHOLD
#define SPEED_GAIN_MIN_SECONDS
#define LATGAP_SPEED_THRESHOLD2
std::pair< const MSVehicle *, double > CLeaderDist
std::pair< const MSPerson *, double > PersonDist
@ SVC_EMERGENCY
public emergency vehicles
@ RIGHT
At the rightmost side of the lane.
@ GIVEN
The position is given.
@ DEFAULT
No information given; use default.
@ LEFT
At the leftmost side of the lane.
@ CENTER
At the center of the lane.
LateralAlignment
Numbers representing special SUMO-XML-attribute values Information how vehicles align themselves with...
@ LATALIGN_RIGHT
drive on the right side
@ LATALIGN_LEFT
drive on the left side
@ LATALIGN_CENTER
drive in the middle
@ LATALIGN_ARBITRARY
maintain the current alignment
@ LATALIGN_NICE
align with the closest sublane border
@ LATALIGN_COMPACT
align with the rightmost sublane that allows keeping the current speed
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ TURN_LEFTHAND
The link is a 180 degree turn (left-hand network)
@ PARTRIGHT
The link is a partial right direction.
@ NODIR
The link has no direction (is a dead end link)
LaneChangeAction
The state of a vehicle's lane-change behavior.
@ LCA_BLOCKED_LEFT
blocked left
@ LCA_KEEPRIGHT
The action is due to the default of keeping right "Rechtsfahrgebot".
@ LCA_BLOCKED
blocked in all directions
@ LCA_URGENT
The action is urgent (to be defined by lc-model)
@ LCA_BLOCKED_BY_RIGHT_LEADER
The vehicle is blocked by right leader.
@ LCA_STAY
Needs to stay on the current lane.
@ LCA_SUBLANE
used by the sublane model
@ LCA_BLOCKED_BY_LEADER
blocked by leader
@ LCA_BLOCKED_BY_LEFT_FOLLOWER
The vehicle is blocked by left follower.
@ LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
@ LCA_COOPERATIVE
The action is done to help someone else.
@ LCA_OVERLAPPING
The vehicle is blocked being overlapping.
@ LCA_LEFT
Wants go to the left.
@ LCA_BLOCKED_RIGHT
blocked right
@ LCA_BLOCKED_BY_RIGHT_FOLLOWER
The vehicle is blocked by right follower.
@ LCA_STRATEGIC
The action is needed to follow the route (navigational lc)
@ LCA_AMBACKBLOCKER_STANDING
@ LCA_CHANGE_REASONS
reasons of lane change
@ LCA_TRACI
The action is due to a TraCI request.
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
@ LCA_WANTS_LANECHANGE
lane can change
@ LCA_RIGHT
Wants go to the right.
@ LCA_BLOCKED_BY_FOLLOWER
blocker by follower
@ LCA_BLOCKED_BY_LEFT_LEADER
@ SUMO_ATTR_LCA_COOPERATIVE_SPEED
@ SUMO_ATTR_LCA_ASSERTIVE
@ SUMO_ATTR_LCA_LANE_DISCIPLINE
@ SUMO_ATTR_LCA_TURN_ALIGNMENT_DISTANCE
@ SUMO_ATTR_LCA_LOOKAHEADLEFT
@ SUMO_ATTR_LCA_SPEEDGAIN_PARAM
@ SUMO_ATTR_LCA_IMPATIENCE
@ SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD
@ SUMO_ATTR_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_LCA_COOPERATIVE_PARAM
@ SUMO_ATTR_LCA_SUBLANE_PARAM
@ SUMO_ATTR_LCA_ACCEL_LAT
@ SUMO_ATTR_LCA_STRATEGIC_PARAM
@ SUMO_ATTR_LCA_TIME_TO_IMPATIENCE
@ SUMO_ATTR_LCA_SPEEDGAINRIGHT
int gPrecision
the precision for floating point outputs
const double SUMO_const_laneWidth
#define UNUSED_PARAMETER(x)
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class responsible for exchanging messages between cars involved in lane-change interaction.
Interface for lane-change models.
double getPreviousManeuverDist() const
virtual void setOwnState(const int state)
int myPreviousState
lane changing state from the previous simulation step
double getManeuverDist() const
Returns the remaining unblocked distance for the current maneuver. (only used by sublane model)
int myOwnState
The current state of the vehicle.
virtual void prepareStep()
double myLastLateralGapRight
double myCommittedSpeed
the speed when committing to a change maneuver
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
static const double NO_NEIGHBOR
int & getCanceledState(const int dir)
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
double myMaxSpeedLatFactor
const LaneChangeModel myModel
the type of this model
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
double mySpeedLat
the current lateral speed
const MSCFModel & myCarFollowModel
The vehicle's car following model.
double myMaxSpeedLatStanding
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
virtual double getArrivalPos() const
Returns this vehicle's desired arrivalPos for its current route (may change on reroute)
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
const MSRoute & getRoute() const
Returns the current route.
The car-following model abstraction.
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
virtual double getSecureGap(const MSVehicle *const, const MSVehicle *const, const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
static double gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1=0, double a2=0, const double maxV1=std::numeric_limits< double >::max(), const double maxV2=std::numeric_limits< double >::max())
return the resulting gap if, starting with gap currentGap, two vehicles continue with constant accele...
virtual double 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.
double getEmergencyDecel() const
Get the vehicle type's maximal phisically possible deceleration [m/s^2].
static double brakeGapEuler(const double speed, const double decel, const double headwayTime)
static double avoidArrivalAccel(double dist, double time, double speed, double maxDecel)
Computes the acceleration needed to arrive not before the given time.
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...
virtual void setMaxDecel(double decel)
Sets a new value for maximal comfortable deceleration [m/s^2].
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle's follow speed (no dawdling)
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
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....
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)
A road/street connecting two junctions.
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
bool isInternal() const
return whether this edge is an internal edge
double getWidth() const
Returns the edges's width (sum over all lanes)
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
const std::vector< double > getSubLaneSides() const
Returns the right side offsets of this edge's sublanes.
static double gLateralResolution
static bool gSemiImplicitEulerUpdate
static bool gLefthand
Whether lefthand-drive is being simulated.
static double getRoundaboutDistBonus(const MSVehicle &veh, double bonusParam, const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, const MSVehicle::LaneQ &best)
Computes the artificial bonus distance for roundabout lanes this additional distance reduces the sens...
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()
double mySafeLatDistRight
the lateral distance the vehicle can safely move in the currently considered direction
static bool overlap(double right, double left, double right2, double left2)
return whether the given intervals overlap
double informLeaders(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds)
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
std::set< const MSVehicle * > myCFRelated
set of vehicles that are in a car-following relationship with ego (leader of followers)
void setOwnState(const int state)
double myKeepRightProbability
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
double myChangeProbThresholdRight
double informLeader(int blocked, int dir, const CLeaderDist &neighLead, double remainingSeconds)
MSLCM_SL2015(MSVehicle &v)
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 ...
int computeSublaneShift(const MSEdge *prevEdge, const MSEdge *curEdge)
compute shift so that prevSublane + shift = newSublane
double myCooperativeSpeed
StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const
decide in which direction to move in case both directions are desirable
void updateExpectedSublaneSpeeds(const MSLeaderDistanceInfo &ahead, int sublaneOffset, int laneIndex)
update expected speeds for each sublane of the current edge
void * inform(void *info, MSVehicle *sender)
std::vector< double > myExpectedSublaneSpeeds
expected travel speeds on all sublanes on the current edge(!)
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, double roundaboutBonus, double latLaneDist, double &latDist)
compute strategic lane change actions TODO: Better documentation, refs #2
double getWidth() const
return the widht of this vehicle (padded for numerical stability)
bool myCanChangeFully
whether the current lane changing maneuver can be finished in a single step
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
bool myDontBrake
flag to prevent speed adaptation by slowing down
void saveBlockerLength(const MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
void updateCFRelated(const MSLeaderDistanceInfo &vehicles, double foeOffset, bool leaders)
find leaders/followers that are already in a car-following relationship with ego
double mySpeedGainProbabilityRight
a value for tracking the probability that a change to the right is beneficial
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
void initDerivedParameters()
init cached parameters derived directly from model parameters
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
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
double myCooperativeParam
double computeSpeedGain(double latDistSublane, double defaultNextSpeed) const
compute speedGain when moving by the given amount
double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
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
const MSEdge * myLastEdge
expected travel speeds on all sublanes on the current edge(!)
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...
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
virtual void updateSafeLatDist(const double travelledLatDist)
Updates the value of safe lateral distances (mySafeLatDistLeft and mySafeLatDistRight) during maneuve...
void msg(const CLeaderDist &cld, double speed, int state)
send a speed recommendation to the given vehicle
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
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
double getLateralDrift()
get lateral drift for the current step
double computeGapFactor(int state) const
compute the gap factor for the given state
double getPosLat()
get lateral position of this vehicle
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...
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 myTurnAlignmentDist
double myLeadingBlockerLength
void informFollowers(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds, double plannedSpeed)
call informFollower for multiple followers
double mySpeedGainLookahead
bool debugVehicle() const
whether the current vehicles shall be debugged
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
double mySpeedLossProbThreshold
double mySpeedGainProbabilityLeft
a value for tracking the probability that a change to the left is beneficial
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
static LaneChangeAction getLCA(int state, double latDist)
compute lane change action from desired lateral distance
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 myChangeProbThresholdLeft
static CLeaderDist getLongest(const MSLeaderDistanceInfo &ldi)
get the longest vehicle in the given info
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
double computeSpeedLat(double latDist, double &maneuverDist) const
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
double myTimeToImpatience
static int lowest_bit(int changeReason)
return the most important change reason
static CLeaderDist getSlowest(const MSLeaderDistanceInfo &ldi)
get the slowest vehicle in the given info
bool amBlockingFollowerPlusNB()
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
std::pair< const MSPerson *, double > nextBlocking(double minPos, double minRight, double maxLeft, double stopTime=0) const
This is just a wrapper around MSPModel::nextBlocking. You should always check using hasPedestrians be...
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
double getLength() const
Returns the lane's length.
bool allowsVehicleClass(SUMOVehicleClass vclass) const
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
double getRightSideOnEdge() const
bool hasPedestrians() const
whether the lane has pedestrians on it
int getIndex() const
Returns the lane's index.
MSEdge & getEdge() const
Returns the lane's edge.
double getWidth() const
Returns the lane's width.
int getRightmostSublane() const
saves leader/follower vehicles and their distances relative to an ego vehicle
virtual std::string toString() const
print a debugging representation
bool hasStoppedVehicle() const
whether a stopped vehicle is leader
void getSublaneBorders(int sublane, double latOffset, double &rightSide, double &leftSide) const
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
const MSEdge * getLastEdge() const
returns the destination edge
const MSLane * lane
The lane to stop at (microsim only)
double getLatDist() const
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
bool ignoreOverlap() const
Representation of a vehicle in the micro simulation.
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)
bool isActive() const
Returns whether the current simulation step is an action point for the vehicle.
MSAbstractLaneChangeModel & getLaneChangeModel()
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
int getBestLaneOffset() const
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
const std::pair< double, LinkDirection > & getNextTurn()
Get the distance and direction of the next upcoming turn for the vehicle (within its look-ahead range...
Influencer & getInfluencer()
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getSpeed() const
Returns the vehicle's current speed.
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
double getPositionOnLane() const
Get the vehicle's position along the lane.
const MSLane * getLane() const
Returns the lane the vehicle is on.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane
bool hasInfluencer() const
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)
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double getMinGapLat() const
Get the minimum lateral gap that vehicles of this type maintain.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double getMinGap() const
Get the free space in front of vehicles of this class.
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
double getLength() const
Get vehicle's length [m].
LateralAlignment getPreferredLateralAlignment() const
Get vehicle's preferred lateral alignment.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
void step(double dt)
evolve for a time step of length dt.
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
bool sameDirection(const StateAndDist &other) const
A structure representing the best lanes for continuing the current route starting at 'lane'.
double length
The overall length which may be driven when using this lane without a lane change.
std::vector< MSLane * > bestContinuations
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive.
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.