40#define MAGIC_OFFSET 1.
41#define LOOK_FORWARD 10.
45#define LCA_RIGHT_IMPATIENCE -1.
46#define CUT_IN_LEFT_SPEED_THRESHOLD 27.
47#define MAX_ONRAMP_LENGTH 200.
49#define LOOK_AHEAD_MIN_SPEED 0.0
50#define LOOK_AHEAD_SPEED_MEMORY 0.9
52#define HELP_DECEL_FACTOR 1.0
54#define HELP_OVERTAKE (10.0 / 3.6)
55#define MIN_FALLBEHIND (7.0 / 3.6)
59#define KEEP_RIGHT_TIME 5.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 ARRIVALPOS_LAT_THRESHOLD 100.0
69#define LATGAP_SPEED_THRESHOLD (50 / 3.6)
72#define LATGAP_SPEED_THRESHOLD2 (50 / 3.6)
75#define SPEEDGAIN_DECAY_FACTOR 0.5
77#define SPEEDGAIN_MEMORY_FACTOR 0.5
79#define REACT_TO_STOPPED_DISTANCE 100
104#define DEBUG_COND (myVehicle.isSelected())
116 mySpeedGainProbabilityRight(0),
117 mySpeedGainProbabilityLeft(0),
118 myKeepRightProbability(0),
119 myLeadingBlockerLength(0),
123 myCanChangeFully(true),
124 mySafeLatDistRight(0),
125 mySafeLatDistLeft(0),
133 myMinGapLat(v.getVehicleType().getMinGapLat()),
136 MAX2(NUMERICAL_EPS, myMinGapLat)) /
137 MAX2(NUMERICAL_EPS, myMinGapLat)))),
140 myMinImpatience(myImpatience),
192 const std::vector<MSVehicle::LaneQ>& preb,
195 double& latDist,
double& maneuverDist,
int& blocked) {
198 const std::string changeType = laneOffset == -1 ?
"right" : (laneOffset == 1 ?
"left" :
"current");
206 <<
" neigh=" << neighLane.
getID()
211 <<
" considerChangeTo=" << changeType
218 leaders, followers, blockers,
219 neighLeaders, neighFollowers, neighBlockers,
221 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
223 result =
keepLatGap(result, leaders, followers, blockers,
224 neighLeaders, neighFollowers, neighBlockers,
225 neighLane, laneOffset, latDist, maneuverDist, blocked);
227 result |=
getLCA(result, latDist);
229#if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE)
230 double latDistTmp = latDist;
233#if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE)
235 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" maneuverDist=" << maneuverDist <<
" latDist=" << latDistTmp <<
" mySpeedPrev=" <<
mySpeedLat <<
" speedLat=" <<
DIST2SPEED(latDist) <<
" latDist2=" << latDist <<
"\n";
242 <<
" wantsChangeTo=" << changeType
243 <<
" latDist=" << latDist
244 <<
" maneuverDist=" << maneuverDist
252 <<
" wantsNoChangeTo=" << changeType
309 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
310#ifdef DEBUG_PATCHSPEED
312 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
319 <<
" wanted=" << wanted
338 double nVSafe = wanted;
344#ifdef DEBUG_PATCHSPEED
352 max =
MIN2(max, safe);
357 if (safe >= vMinEmergency) {
359 min =
MAX2(vMinEmergency, safe);
362#ifdef DEBUG_PATCHSPEED
364 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe + NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
367 nVSafe =
MAX2(min, safe);
374 double accel = i.first;
376 if (v >= min && v <= max) {
379 nVSafe =
MIN2(v, nVSafe);
381 nVSafe =
MIN2(v * coopWeight + (1 - coopWeight) * wanted, nVSafe);
384#ifdef DEBUG_PATCHSPEED
386 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" got accel=" << accel <<
" nVSafe=" << nVSafe <<
"\n";
390#ifdef DEBUG_PATCHSPEED
393 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" (accel=" << accel <<
") min=" << min <<
"\n";
397 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" (accel=" << accel <<
") max=" << max <<
"\n";
405#ifdef DEBUG_PATCHSPEED
418#if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
423 return (max + wanted) / 2.0;
427#if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
432 return (min + wanted) / 2.0;
435#if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
440 return (max + wanted) / 2.0;
481#if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
486 return (max + wanted) / 2.0;
490#if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE)
510 if (pinfo->first >= 0) {
519 <<
" informedBy=" << sender->
getID()
520 <<
" info=" << pinfo->second
521 <<
" vSafe=" << pinfo->first
534 assert(cld.first != 0);
543 double remainingSeconds) {
549 plannedSpeed =
MIN2(plannedSpeed, v);
554 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
565 if (
gDebugFlag2) std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
569 const double dv = plannedSpeed - nv->
getSpeed();
570 const double overtakeDist = (neighLead.second
582 || dv * remainingSeconds < overtakeDist)
583 && (!neighLead.first->isStopped() || (
isOpposite() && neighLead.second >= 0))) {
598 <<
" cannot overtake leader nv=" << nv->
getID()
600 <<
" remainingSeconds=" << remainingSeconds
601 <<
" targetSpeed=" << targetSpeed
602 <<
" nextSpeed=" << nextSpeed
613 <<
" cannot overtake fast leader nv=" << nv->
getID()
615 <<
" remainingSeconds=" << remainingSeconds
616 <<
" targetSpeed=" << targetSpeed
627 <<
" wants to overtake leader nv=" << nv->
getID()
629 <<
" remainingSeconds=" << remainingSeconds
630 <<
" currentGap=" << neighLead.second
632 <<
" overtakeDist=" << overtakeDist
642 }
else if (neighLead.first != 0) {
645 double dv, nextNVSpeed;
665 std::cout <<
" not blocked by leader nv=" << nv->
getID()
667 <<
" gap=" << neighLead.second
668 <<
" nextGap=" << neighLead.second - dv
670 <<
" targetSpeed=" << targetSpeed
674 return MIN2(targetSpeed, plannedSpeed);
686 double remainingSeconds,
687 double plannedSpeed) {
695 if (
gDebugFlag2) std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap="
702 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
705 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
724 const double neighNewSpeed1s =
MAX2(0., nv->
getSpeed() - helpDecel);
725 const double dv = plannedSpeed - neighNewSpeed1s;
727 const double decelGap = neighFollow.second + dv;
733 <<
" egoNV=" << plannedSpeed
734 <<
" nvNewSpeed=" << neighNewSpeed
735 <<
" nvNewSpeed1s=" << neighNewSpeed1s
736 <<
" deltaGap=" << dv
737 <<
" decelGap=" << decelGap
738 <<
" secGap=" << secureGap
742 if (decelGap > 0 && decelGap >= secureGap) {
757 std::cout <<
" wants to cut in before nv=" << nv->
getID()
758 <<
" vsafe1=" << vsafe1
759 <<
" vsafe=" << vsafe
764 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap + POSITION_EPS)) {
769 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
777 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
793 std::cout <<
" wants right follower to slow down a bit\n";
799 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
808 const double overtakeDist = (neighFollow.second
814 const double needDV = overtakeDist / remainingSeconds;
822 <<
" wants to be overtaken by=" << nv->
getID()
823 <<
" overtakeDist=" << overtakeDist
825 <<
" vhelp=" << vhelp
826 <<
" needDV=" << needDV
832 }
else if (neighFollow.first != 0) {
837 std::cout <<
" wants to cut in before non-blocking follower nv=" << neighFollow.first->getID() <<
"\n";
845 const std::vector<CLeaderDist>& blockers,
846 double remainingSeconds) {
858 plannedSpeed =
MIN2(plannedSpeed, safe);
860 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
861 plannedSpeed =
MIN2(plannedSpeed,
informLeader(blocked, dir, *it, remainingSeconds));
869 const std::vector<CLeaderDist>& blockers,
870 double remainingSeconds,
871 double plannedSpeed) {
873 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
874 informFollower(blocked, dir, *it, remainingSeconds, plannedSpeed);
899 const double halfWidth =
getWidth() * 0.5;
912 std::vector<double> newExpectedSpeeds;
921 const std::vector<MSLane*>& lanes = currEdge->
getLanes();
922 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
924 for (
int i = 0; i < subLanes; ++i) {
925 newExpectedSpeeds.push_back((*it_lane)->getVehicleMaxSpeed(&
myVehicle));
931 for (
int i = 0; i < subLanes; ++i) {
932 newExpectedSpeeds.push_back(lanes.back()->getVehicleMaxSpeed(&
myVehicle));
940 if (subLaneShift < std::numeric_limits<int>::max()) {
942 const int newI = i + subLaneShift;
943 if (newI > 0 && newI < (
int)newExpectedSpeeds.size()) {
961 if (bestLaneOffset < -1) {
963 }
else if (bestLaneOffset > 1) {
990 for (
const MSLink*
const link : lane->getLinkCont()) {
991 if (&link->getLane()->getEdge() == curEdge) {
993 const MSLane* target = link->getLane();
994 const std::vector<MSLane*>& lanes2 = curEdge->
getLanes();
995 for (std::vector<MSLane*>::const_iterator it_lane2 = lanes2.begin(); it_lane2 != lanes2.end(); ++it_lane2) {
996 const MSLane* lane2 = *it_lane2;
997 if (lane2 == target) {
998 return prevShift + curShift;
1009 return std::numeric_limits<int>::max();
1043#if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE)
1076 const std::vector<MSVehicle::LaneQ>& preb,
1079 double& latDist,
double& maneuverDist,
int& blocked) {
1081 if (laneOffset != 0) {
1083 const double halfWidth =
getWidth() * 0.5;
1085 if (laneOffset < 0) {
1095 int bestLaneOffset = 0;
1096 double currentDist = 0;
1097 double neighDist = 0;
1109 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1110 for (
int p = 0; p < (int) preb.size(); ++p) {
1111 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1112 assert(p + prebOffset < (
int)preb.size());
1114 neigh = preb[p + prebOffset];
1115 currentDist = curr.
length;
1116 neighDist = neigh.
length;
1119 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0 && !checkOpposite) {
1120#ifdef DEBUG_WANTSCHANGE
1124 <<
" bestLaneOffsetOld=" << bestLaneOffset
1125 <<
" bestLaneOffsetNew=" << laneOffset
1129 bestLaneOffset = prebOffset;
1131 best = preb[p + bestLaneOffset];
1135 assert(curr.
lane !=
nullptr);
1136 assert(neigh.
lane !=
nullptr);
1137 assert(best.
lane !=
nullptr);
1138 double driveToNextStop = -std::numeric_limits<double>::max();
1147#ifdef DEBUG_WANTS_CHANGE
1152 <<
" stopPos=" << stopPos
1153 <<
" currentDist=" << currentDist
1154 <<
" neighDist=" << neighDist
1158 currentDist =
MAX2(currentDist, stopPos);
1159 neighDist =
MAX2(neighDist, stopPos);
1162 const bool right = (laneOffset == -1);
1163 const bool left = (laneOffset == 1);
1166 const bool changeToBest = (right && bestLaneOffset < 0) || (left && bestLaneOffset > 0) || (laneOffset == 0 && bestLaneOffset == 0);
1192#ifdef DEBUG_WANTSCHANGE
1199 <<
"\n leaders=" << leaders.
toString()
1200 <<
"\n followers=" << followers.
toString()
1201 <<
"\n blockers=" << blockers.
toString()
1202 <<
"\n neighLeaders=" << neighLeaders.
toString()
1203 <<
"\n neighFollowers=" << neighFollowers.
toString()
1204 <<
"\n neighBlockers=" << neighBlockers.
toString()
1205 <<
"\n changeToBest=" << changeToBest
1206 <<
" latLaneDist=" << latLaneDist
1214 if (lastBlocked != firstBlocked) {
1265 for (
int i = 0; i < neighLeaders.
numSublanes(); ++i) {
1267 if (vehDist.first !=
nullptr && vehDist.first->isStopped()) {
1285 currentDist += roundaboutBonus;
1286 neighDist += roundaboutBonus;
1288 if (laneOffset != 0) {
1306 if ((ret &
LCA_STAY) != 0 && latDist == 0) {
1319 if (changeToBest && abs(bestLaneOffset) > 1
1325#ifdef DEBUG_WANTSCHANGE
1327 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1336#ifdef DEBUG_WANTSCHANGE
1342 if (*firstBlocked != neighLeadLongest &&
tieBrakeLeader(*firstBlocked)) {
1351 std::vector<CLeaderDist> collectLeadBlockers;
1352 std::vector<CLeaderDist> collectFollowBlockers;
1353 int blockedFully = 0;
1354 maneuverDist = latDist;
1356 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1357 leaders, followers, blockers,
1358 neighLeaders, neighFollowers, neighBlockers, &collectLeadBlockers, &collectFollowBlockers,
1359 false, gapFactor, &blockedFully);
1361 const double absLaneOffset = fabs(bestLaneOffset != 0 ? bestLaneOffset : latDist /
SUMO_const_laneWidth);
1362 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1365 const double plannedSpeed =
informLeaders(blocked, myLca, collectLeadBlockers, remainingSeconds);
1367 if (plannedSpeed >= 0) {
1369 informFollowers(blocked, myLca, collectFollowBlockers, remainingSeconds, plannedSpeed);
1371 if (plannedSpeed > 0) {
1372 commitManoeuvre(blocked, blockedFully, leaders, neighLeaders, neighLane, maneuverDist);
1374#if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE)
1381 <<
" remainingSeconds=" << remainingSeconds
1382 <<
" plannedSpeed=" << plannedSpeed
1393 if (roundaboutBonus > 0) {
1395#ifdef DEBUG_WANTS_CHANGE
1399 <<
" roundaboutBonus=" << roundaboutBonus
1410 latDist = latLaneDist;
1411 maneuverDist = latLaneDist;
1412 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1413 leaders, followers, blockers,
1414 neighLeaders, neighFollowers, neighBlockers);
1418 ret &= ~LCA_COOPERATIVE;
1434 const double inconvenience = (latLaneDist < 0
1437#ifdef DEBUG_COOPERATE
1445 <<
" inconvenience=" << inconvenience
1447 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1464 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1467#ifdef DEBUG_COOPERATE
1469 std::cout <<
" wants cooperative change\n";
1476 maneuverDist = latDist;
1477 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1478 leaders, followers, blockers,
1479 neighLeaders, neighFollowers, neighBlockers);
1505 const double vehWidth =
getWidth();
1507 const double leftVehSide = rightVehSide + vehWidth;
1509 double defaultNextSpeed = std::numeric_limits<double>::max();
1511 int leftmostOnEdge = (int)sublaneSides.size() - 1;
1512 while (leftmostOnEdge > 0 && sublaneSides[leftmostOnEdge] > leftVehSide) {
1515 int rightmostOnEdge = leftmostOnEdge;
1516 while (rightmostOnEdge > 0 && sublaneSides[rightmostOnEdge] > rightVehSide + NUMERICAL_EPS) {
1518#ifdef DEBUG_WANTSCHANGE
1520 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1521 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1527#ifdef DEBUG_WANTSCHANGE
1529 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1530 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1533 double maxGain = -std::numeric_limits<double>::max();
1534 double maxGainRight = -std::numeric_limits<double>::max();
1535 double maxGainLeft = -std::numeric_limits<double>::max();
1536 double latDistNice = std::numeric_limits<double>::max();
1539 double leftMax =
MAX2(
1546 assert(leftMax <= edge.
getWidth());
1548 int sublaneCompact =
MAX2(iMin, rightmostOnEdge - 1);
1554 const double maxLatDist = leftMax - leftVehSide;
1555 const double minLatDist = rightMin - rightVehSide;
1556 const int iStart = laneOffset == 0 ? iMin : 0;
1557 const double rightEnd = laneOffset == 0 ? leftMax : (checkOpposite ?
getLeftBorder() : edge.
getWidth());
1558#ifdef DEBUG_WANTSCHANGE
1560 <<
" checking sublanes rightmostOnEdge=" << rightmostOnEdge
1561 <<
" rightEnd=" << rightEnd
1562 <<
" leftmostOnEdge=" << leftmostOnEdge
1563 <<
" iStart=" << iStart
1565 <<
" sublaneSides=" << sublaneSides.size()
1566 <<
" leftMax=" << leftMax
1567 <<
" minLatDist=" << minLatDist
1568 <<
" maxLatDist=" << maxLatDist
1569 <<
" sublaneCompact=" << sublaneCompact
1572 for (
int i = iStart; i < (int)sublaneSides.size(); ++i) {
1573 if (sublaneSides[i] + vehWidth < rightEnd) {
1579 while (vMin > 0 && j < (
int)sublaneSides.size() && sublaneSides[j] < sublaneSides[i] + vehWidth) {
1585 if (laneOffset != 0 &&
overlap(sublaneSides[i], sublaneSides[i] + vehWidth, laneBoundary, laneBoundary)) {
1589 const double currentLatDist =
MIN2(
MAX2(sublaneSides[i] - rightVehSide, minLatDist), maxLatDist);
1593 relativeGain *= 0.5;
1596 if (relativeGain > maxGain) {
1597 maxGain = relativeGain;
1600 latDist = currentLatDist;
1601#ifdef DEBUG_WANTSCHANGE
1603 std::cout <<
" i=" << i <<
" newLatDist=" << latDist <<
" relGain=" << relativeGain <<
"\n";
1609 if (currentLatDist > 0
1613 && maxGain - relativeGain < NUMERICAL_EPS) {
1614 latDist = currentLatDist;
1617#ifdef DEBUG_WANTSCHANGE
1619 std::cout <<
" i=" << i <<
" rightmostOnEdge=" << rightmostOnEdge <<
" vMin=" << vMin <<
" relGain=" << relativeGain <<
" sublaneCompact=" << sublaneCompact <<
" curLatDist=" << currentLatDist <<
"\n";
1623 maxGainRight =
MAX2(maxGainRight, relativeGain);
1625 maxGainLeft =
MAX2(maxGainLeft, relativeGain);
1627 const double subAlignDist = sublaneSides[i] - rightVehSide;
1628 if (fabs(subAlignDist) < fabs(latDistNice)) {
1629 latDistNice = subAlignDist;
1630#ifdef DEBUG_WANTSCHANGE
1632 <<
" nicest sublane=" << i
1633 <<
" side=" << sublaneSides[i]
1634 <<
" rightSide=" << rightVehSide
1635 <<
" latDistNice=" << latDistNice
1636 <<
" maxGainR=" << maxGainRight
1637 <<
" maxGainL=" << maxGainLeft
1644 if (maxGainRight != -std::numeric_limits<double>::max()) {
1645#ifdef DEBUG_WANTSCHANGE
1651#ifdef DEBUG_WANTSCHANGE
1657 if (maxGainLeft != -std::numeric_limits<double>::max()) {
1658#ifdef DEBUG_WANTSCHANGE
1664#ifdef DEBUG_WANTSCHANGE
1671 if ((fabs(maxGainRight) < NUMERICAL_EPS || maxGainRight == -std::numeric_limits<double>::max())
1672 && (right || (alternatives &
LCA_RIGHT) == 0)) {
1675 if ((fabs(maxGainLeft) < NUMERICAL_EPS || maxGainLeft == -std::numeric_limits<double>::max())
1676 && (left || (alternatives &
LCA_LEFT) == 0)) {
1681#ifdef DEBUG_WANTSCHANGE
1684 <<
" defaultNextSpeed=" << defaultNextSpeed
1685 <<
" maxGain=" << maxGain
1686 <<
" maxGainRight=" << maxGainRight
1687 <<
" maxGainLeft=" << maxGainLeft
1688 <<
" latDist=" << latDist
1689 <<
" latDistNice=" << latDistNice
1690 <<
" sublaneCompact=" << sublaneCompact
1703 double acceptanceTime;
1712 double minFactor = 1.0;
1713 for (
int i = 0; i < followers.
numSublanes(); ++i) {
1715 if (follower.first !=
nullptr && follower.second < 2 * follower.first->getCarFollowModel().brakeGap(follower.first->getSpeed())) {
1718 const double fRSF = follower.first->getLane()->getVehicleMaxSpeed(follower.first) / follower.first->getLane()->getSpeedLimit();
1719 if (fRSF > roadSpeedFactor) {
1722 if (factor < minFactor) {
1728 acceptanceTime *= minFactor;
1732 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1734 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1735 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1737 vMax, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1738 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1747#ifdef DEBUG_WANTSCHANGE
1750 <<
" considering keepRight:"
1752 <<
" neighDist=" << neighDist
1754 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1756 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1757 <<
" acceptanceTime=" << acceptanceTime
1758 <<
" fullSpeedGap=" << fullSpeedGap
1759 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1760 <<
" dProb=" << deltaProb
1761 <<
" isSlide=" << isSlide
1772 latDist = latLaneDist;
1773 maneuverDist = latLaneDist;
1774 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1775 leaders, followers, blockers,
1776 neighLeaders, neighFollowers, neighBlockers);
1779 ret &= ~LCA_KEEPRIGHT;
1785#ifdef DEBUG_WANTSCHANGE
1790 <<
" neighDist=" << neighDist
1794 <<
" latDist=" << latDist
1804 int blockedFully = 0;
1805 maneuverDist = latDist;
1806 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1807 leaders, followers, blockers,
1808 neighLeaders, neighFollowers, neighBlockers,
1809 nullptr,
nullptr,
false, 0, &blockedFully);
1815 ret &= ~LCA_SPEEDGAIN;
1822#ifdef DEBUG_WANTSCHANGE
1827 <<
" latDist=" << latDist
1828 <<
" neighDist=" << neighDist
1831 <<
" stayInLane=" << stayInLane
1842 int blockedFully = 0;
1843 maneuverDist = latDist;
1844 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1845 leaders, followers, blockers,
1846 neighLeaders, neighFollowers, neighBlockers,
1847 nullptr,
nullptr,
false, 0, &blockedFully);
1852 ret &= ~LCA_SPEEDGAIN;
1857 double latDistSublane = 0.;
1859 const double halfVehWidth =
getWidth() * 0.5;
1862 && bestLaneOffset == 0
1882#ifdef DEBUG_WANTSCHANGE
1893 latDistSublane = -halfLaneWidth + halfVehWidth -
getPosLat();
1896 latDistSublane = halfLaneWidth - halfVehWidth -
getPosLat();
1903 latDistSublane = latDistNice;
1906 latDistSublane = sublaneSides[sublaneCompact] - rightVehSide;
1924 latDistSublane * latDist > 0) {
1926#if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) || defined(DEBUG_MANEUVER)
1931 <<
" latDist=" << latDist
1932 <<
" latDistSublane=" << latDistSublane
1933 <<
" relGainSublane=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed)
1934 <<
" maneuverDist=" << maneuverDist
1946#if defined(DEBUG_WANTSCHANGE)
1948 <<
" speedGain=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed) <<
")\n";
1956#if defined(DEBUG_WANTSCHANGE)
1958 std::cout <<
" aborting sublane change due to prior maneuver\n";
1963 latDist = latDistSublane * (
isOpposite() ? -1 : 1);
1968#ifdef DEBUG_WANTSCHANGE
1971 <<
" latDist=" << latDist
1979#ifdef DEBUG_WANTSCHANGE
1985 maneuverDist = latDist;
1986 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1987 leaders, followers, blockers,
1988 neighLeaders, neighFollowers, neighBlockers);
1991 ret &= ~LCA_SUBLANE;
2017#ifdef DEBUG_WANTSCHANGE
2034 if ((*blocked) !=
nullptr) {
2036#ifdef DEBUG_SLOWDOWN
2045 if (gap > POSITION_EPS) {
2059 (gap - POSITION_EPS), (*blocked)->getSpeed(),
2060 (*blocked)->getCarFollowModel().getMaxDecel()),
false);
2078 if (cand !=
nullptr && cand->getBidiLane() == lane) {
2092 assert(preb.size() == lanes.size() ||
isOpposite());
2093#ifdef DEBUG_EXPECTED_SLSPEED
2096 <<
" sublaneOffset=" << sublaneOffset <<
" laneIndex=" << laneIndex <<
" lane=" << lane->
getID() <<
" ahead=" << ahead.
toString() <<
"\n";
2100 for (
int sublane = 0; sublane < (int)ahead.
numSublanes(); ++sublane) {
2101 const int edgeSublane = sublane + sublaneOffset;
2109 const MSVehicle* leader = ahead[sublane].first;
2110 const double gap = ahead[sublane].second;
2112 if (leader ==
nullptr) {
2117 const int prebIndex =
isOpposite() ? (int)preb.size() - 1 : laneIndex;
2128#ifdef DEBUG_EXPECTED_SLSPEED
2130 std::cout <<
SIMTIME <<
" updateExpectedSublaneSpeeds sublane=" << sublane <<
" leader=" << leader->
getID() <<
" bidi=" << bidi->
getID() <<
" gap=" << gap <<
" vSafe=" << vSafe <<
"\n";
2140#ifdef DEBUG_EXPECTED_SLSPEED
2142 std::cout <<
" updateExpectedSublaneSpeeds edgeSublane=" << edgeSublane <<
" leader=" << leader->
getID() <<
" gap=" << gap <<
" vSafe=" << vSafe <<
"\n";
2151 double foeRight, foeLeft;
2155 if (pedLeader.first != 0) {
2160#ifdef DEBUG_EXPECTED_SLSPEED
2162 std::cout <<
" updateExpectedSublaneSpeeds edgeSublane=" << edgeSublane <<
" pedLeader=" << pedLeader.first->getID() <<
" gap=" << pedGap <<
" vSafe=" << vSafe <<
"\n";
2170 double foeRight, foeLeft;
2172 const double foeRightBidi = bidi->
getWidth() - foeLeft;
2173 const double foeLeftBidi = bidi->
getWidth() - foeRight;
2178 if (pedLeader.first != 0) {
2183#ifdef DEBUG_EXPECTED_SLSPEED
2185 std::cout <<
" updateExpectedSublaneSpeeds edgeSublane=" << edgeSublane <<
" pedLeader=" << pedLeader.first->getID() <<
" (bidi) gap=" << pedGap <<
" vSafe=" << vSafe <<
"\n";
2190 vSafe =
MIN2(vMax, vSafe);
2205 const double deltaV = vMax - vLeader;
2206 if (deltaV > 0 && gap / deltaV < mySpeedGainLookahead && mySpeedGainLookahead > 0) {
2210 const double gapClosingTime =
MAX2(0.0, gap / deltaV);
2211 const double vSafe2 = (gapClosingTime * vSafe + (foreCastTime - gapClosingTime) * vLeader) / foreCastTime;
2212#ifdef DEBUG_EXPECTED_SLSPEED
2214 std::cout <<
" foreCastTime=" << foreCastTime <<
" gapClosingTime=" << gapClosingTime <<
" extrapolated vSafe=" << vSafe2 <<
"\n";
2225 double result = std::numeric_limits<double>::max();
2227 const double vehWidth =
getWidth();
2229 const double leftVehSide = rightVehSide + vehWidth;
2230 for (
int i = 0; i < (int)sublaneSides.size(); ++i) {
2232 if (
overlap(rightVehSide, leftVehSide, sublaneSides[i], leftSide)) {
2237 return result - defaultNextSpeed;
2244 double maxLength = -1;
2255 return iMax >= 0 ? ldi[iMax] : std::make_pair(
nullptr, -1);
2272 double minSpeed = std::numeric_limits<double>::max();
2274 if (ldi[i].first != 0) {
2275 const double speed = ldi[i].first->getSpeed();
2276 if (speed < minSpeed) {
2294 std::vector<CLeaderDist>* collectLeadBlockers,
2295 std::vector<CLeaderDist>* collectFollowBlockers,
2296 bool keepLatGapManeuver,
2298 int* retBlockedFully) {
2301 latDist =
MAX2(
MIN2(latDist, maxDist), -maxDist);
2310 if (laneOffset != 0) {
2321 if (laneOffset != 0) {
2325#ifdef DEBUG_BLOCKING
2337 }
else if (!forcedTraCIChange) {
2343 }
else if (!forcedTraCIChange) {
2349#ifdef DEBUG_BLOCKING
2351 std::cout <<
" checkBlocking fully=" <<
myCanChangeFully <<
" latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
"\n";
2365 if (laneOffset != 0) {
2372 int blockedFully = 0;
2377 if (laneOffset != 0) {
2383 if (retBlockedFully !=
nullptr) {
2384 *retBlockedFully = blockedFully;
2391 blocked |= blockedFully;
2396 if (collectFollowBlockers !=
nullptr && collectLeadBlockers !=
nullptr) {
2398 for (std::vector<CLeaderDist>::const_iterator it2 = collectLeadBlockers->begin(); it2 != collectLeadBlockers->end(); ++it2) {
2399 for (std::vector<CLeaderDist>::iterator it = collectFollowBlockers->begin(); it != collectFollowBlockers->end();) {
2400 if ((*it2).first == (*it).first) {
2401#ifdef DEBUG_BLOCKING
2403 std::cout <<
" removed follower " << (*it).first->getID() <<
" because it is already a leader\n";
2406 it = collectFollowBlockers->erase(it);
2420 int laneOffset,
double latDist,
double foeOffset,
bool leaders,
2421 double& safeLatGapRight,
double& safeLatGapLeft,
2422 std::vector<CLeaderDist>* collectBlockers)
const {
2429 const double vehWidth =
getWidth();
2431 const double leftVehSide = rightVehSide + vehWidth;
2432 const double rightVehSideDest = rightVehSide + latDist;
2433 const double leftVehSideDest = leftVehSide + latDist;
2434 const double rightNoOverlap =
MIN2(rightVehSideDest, rightVehSide);
2435 const double leftNoOverlap =
MAX2(leftVehSideDest, leftVehSide);
2436#ifdef DEBUG_BLOCKING
2438 std::cout <<
" checkBlockingVehicles"
2439 <<
" laneOffset=" << laneOffset
2440 <<
" latDist=" << latDist
2441 <<
" foeOffset=" << foeOffset
2442 <<
" vehRight=" << rightVehSide
2443 <<
" vehLeft=" << leftVehSide
2444 <<
" rightNoOverlap=" << rightNoOverlap
2445 <<
" leftNoOverlap=" << leftNoOverlap
2446 <<
" destRight=" << rightVehSideDest
2447 <<
" destLeft=" << leftVehSideDest
2448 <<
" leaders=" << leaders
2454 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2456 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2457 const MSVehicle* leader = vehDist.first;
2463 double foeRight, foeLeft;
2465 const bool overlapBefore =
overlap(rightVehSide, leftVehSide, foeRight, foeLeft);
2466 const bool overlapDest =
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft);
2467 const bool overlapAny =
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft);
2468#ifdef DEBUG_BLOCKING
2470 std::cout <<
" foe=" << vehDist.first->getID()
2471 <<
" gap=" << vehDist.second
2473 <<
" foeRight=" << foeRight
2474 <<
" foeLeft=" << foeLeft
2475 <<
" overlapBefore=" << overlapBefore
2476 <<
" overlap=" << overlapAny
2477 <<
" overlapDest=" << overlapDest
2482 if (vehDist.second < 0) {
2483 if (overlapBefore && !overlapDest && !
outsideEdge()) {
2484#ifdef DEBUG_BLOCKING
2486 std::cout <<
" ignoring current overlap to come clear\n";
2490#ifdef DEBUG_BLOCKING
2496 if (collectBlockers ==
nullptr) {
2499 collectBlockers->push_back(vehDist);
2515 const double expectedGap =
MSCFModel::gapExtrapolation(timeTillAction, vehDist.second, leader->
getSpeed(), follower->
getSpeed(), leaderAccel, followerAccel, std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
2518 const double followerExpectedSpeed = follower->
getSpeed() + timeTillAction * followerAccel;
2519 const double leaderExpectedSpeed =
MAX2(0., leader->
getSpeed() + timeTillAction * leaderAccel);
2522#if defined(DEBUG_ACTIONSTEPS) && defined(DEBUG_BLOCKING)
2524 std::cout <<
" timeTillAction=" << timeTillAction
2525 <<
" followerAccel=" << followerAccel
2526 <<
" followerExpectedSpeed=" << followerExpectedSpeed
2527 <<
" leaderAccel=" << leaderAccel
2528 <<
" leaderExpectedSpeed=" << leaderExpectedSpeed
2529 <<
"\n gap=" << vehDist.second
2530 <<
" gapChange=" << (expectedGap - vehDist.second)
2531 <<
" expectedGap=" << expectedGap
2532 <<
" expectedSecureGap=" << expectedSecureGap
2533 <<
" safeLatGapLeft=" << safeLatGapLeft
2534 <<
" safeLatGapRight=" << safeLatGapRight
2541 if (expectedGap < secureGap2) {
2543 if (foeRight > leftVehSide) {
2544 safeLatGapLeft =
MIN2(safeLatGapLeft, foeRight - leftVehSide);
2545 }
else if (foeLeft < rightVehSide) {
2546 safeLatGapRight =
MIN2(safeLatGapRight, rightVehSide - foeLeft);
2549#ifdef DEBUG_BLOCKING
2551 std::cout <<
" blocked by " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2552 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor()
2553 <<
" safeLatGapLeft=" << safeLatGapLeft <<
" safeLatGapRight=" << safeLatGapRight
2557 result |= blockType;
2558 if (collectBlockers ==
nullptr) {
2561#ifdef DEBUG_BLOCKING
2562 }
else if (
gDebugFlag2 && expectedGap < expectedSecureGap) {
2563 std::cout <<
" ignore blocker " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2564 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor() <<
"\n";
2567 if (collectBlockers !=
nullptr) {
2570 collectBlockers->push_back(vehDist);
2587 const double leftVehSide = rightVehSide + vehWidth;
2588#ifdef DEBUG_BLOCKING
2590 std::cout <<
" updateCFRelated foeOffset=" << foeOffset <<
" vehicles=" << vehicles.
toString() <<
"\n";
2593 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2595 if (vehDist.first != 0 && (
myCFRelated.count(vehDist.first) == 0 || vehDist.second < 0)) {
2596 double foeRight, foeLeft;
2598#ifdef DEBUG_BLOCKING
2600 std::cout <<
" foe=" << vehDist.first->getID() <<
" gap=" << vehDist.second
2602 <<
" foeOffset=" << foeOffset
2603 <<
" egoR=" << rightVehSide <<
" egoL=" << leftVehSide
2604 <<
" iR=" << foeRight <<
" iL=" << foeLeft
2610 if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft) && !
outsideEdge() && (vehDist.second >= 0
2616 && -vehDist.second < vehDist.first->getVehicleType().getMinGap()
2619#ifdef DEBUG_BLOCKING
2621 std::cout <<
" ignoring cfrelated foe=" << vehDist.first->getID() <<
"\n";
2626 const int erased = (int)
myCFRelated.erase(vehDist.first);
2627#ifdef DEBUG_BLOCKING
2629 std::cout <<
" restoring cfrelated foe=" << vehDist.first->getID() <<
"\n";
2642 assert(right <= left);
2643 assert(right2 <= left2);
2644 return left2 >= right + NUMERICAL_EPS && left >= right2 + NUMERICAL_EPS;
2665 return changeReason;
2672 if (sd1.
state == 0) {
2674 }
else if (sd2.
state == 0) {
2684#ifdef DEBUG_WANTSCHANGE
2690 <<
" dir1=" << sd1.
dir
2694 <<
" dir2=" << sd2.
dir
2710 if (reason1 < reason2) {
2712 return (!can1 && can2 && sd1.
sameDirection(sd2)) ? sd2 : sd1;
2714 }
else if (reason1 > reason2) {
2716 return (!can2 && can1 && sd1.
sameDirection(sd2)) ? sd1 : sd2;
2724 }
else if (sd2.
dir == 0) {
2729 assert(sd1.
dir == -1);
2730 assert(sd2.
dir == 1);
2733 }
else if (sd2.
latDist >= 0) {
2782 double roundaboutBonus,
2787 const bool right = (laneOffset == -1);
2788 const bool left = (laneOffset == 1);
2795 const double neighLeftPlace =
MAX2(0., neighDist - forwardPos - maxJam);
2798#ifdef DEBUG_STRATEGIC_CHANGE
2802 <<
" forwardPos=" << forwardPos
2804 <<
" laDist=" << laDist
2805 <<
" currentDist=" << currentDist
2806 <<
" usableDist=" << usableDist
2807 <<
" bestLaneOffset=" << bestLaneOffset
2808 <<
" best.length=" << best.
length
2809 <<
" maxJam=" << maxJam
2810 <<
" neighLeftPlace=" << neighLeftPlace
2816 if (laneOffset != 0 && changeToBest && bestLaneOffset == curr.
bestLaneOffset
2819 latDist = latLaneDist;
2836#ifdef DEBUG_STRATEGIC_CHANGE
2839 <<
" avoid overtaking on the right nv=" << nv->
getID()
2851 if (laneOffset != 0 &&
myStrategicParam >= 0 && noOpposites &&
mustOvertakeStopped(neighLane, leaders, neighLeaders, forwardPos, neighDist, right, latLaneDist, currentDist, latDist)) {
2858 }
else if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
2865#ifdef DEBUG_STRATEGIC_CHANGE
2867 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
2873 && bestLaneOffset == 0
2876 && roundaboutBonus == 0
2883#ifdef DEBUG_STRATEGIC_CHANGE
2885 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
2890 && bestLaneOffset == 0
2896#ifdef DEBUG_STRATEGIC_CHANGE
2898 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
2912 MSLane* shadowPrev =
nullptr;
2914 if (*it ==
nullptr) {
2918 if (shadow ==
nullptr || currentShadowDist >= requiredDist) {
2921 if (shadowPrev !=
nullptr) {
2924 currentShadowDist += shadow->
getLength();
2925 shadowPrev = shadow;
2926#ifdef DEBUG_STRATEGIC_CHANGE
2928 std::cout <<
" shadow=" << shadow->
getID() <<
" currentShadowDist=" << currentShadowDist <<
"\n";
2932#ifdef DEBUG_STRATEGIC_CHANGE
2937 if (currentShadowDist < requiredDist && currentShadowDist < usableDist) {
2940#ifdef DEBUG_STRATEGIC_CHANGE
2942 std::cout <<
" must change for shadowLane end latDist=" << latDist <<
" myLeftSpace=" <<
myLeftSpace <<
"\n";
2950#if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI)
2962 }
else if (((retTraCI &
LCA_RIGHT) != 0 && laneOffset < 0)
2963 || ((retTraCI &
LCA_LEFT) != 0 && laneOffset > 0)) {
2965 latDist = latLaneDist;
2968#if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI)
2979 double posOnLane,
double neighDist,
bool right,
double latLaneDist,
double& currentDist,
double& latDist) {
2980 bool mustOvertake =
false;
2987 if (curHasStopped) {
2989 for (
int i = rightmost; i <= leftmost; i++) {
2994 MIN2(neighDist, currentDist) - posOnLane > overtakeDist
2996 && (!checkOverTakeRight || !right)
3004 latDist = latLaneDist;
3005 mustOvertake =
true;
3006#ifdef DEBUG_WANTS_CHANGE
3008 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" overtake stopped leader=" << leader.first->getID()
3009 <<
" overtakeDist=" << overtakeDist
3010 <<
" remaining=" <<
MIN2(neighDist, currentDist) - posOnLane
3023 for (
int i = 0; i < neighLead.
numSublanes(); i++) {
3026 mustOvertake =
true;
3027 if (i >= rightmost && i <= leftmost) {
3034 return mustOvertake;
3055 double& maneuverDist,
3091 const double oldLatDist = latDist;
3092 const double oldManeuverDist = maneuverDist;
3097 const double halfWidth =
getWidth() * 0.5;
3103 double surplusGapRight = oldCenter - halfWidth;
3104 double surplusGapLeft =
getLeftBorder(laneOffset != 0) - oldCenter - halfWidth;
3105 const bool stayInLane = (laneOffset == 0
3109 && (surplusGapLeft >= 0 && surplusGapRight >= 0)));
3112 std::swap(surplusGapLeft, surplusGapRight);
3114#ifdef DEBUG_KEEP_LATGAP
3116 std::cout <<
"\n " <<
SIMTIME <<
" keepLatGap() laneOffset=" << laneOffset
3117 <<
" latDist=" << latDist
3118 <<
" maneuverDist=" << maneuverDist
3122 <<
" gapFactor=" << gapFactor
3123 <<
" stayInLane=" << stayInLane <<
"\n"
3124 <<
" stayInEdge: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
3128 if (surplusGapLeft < 0 || surplusGapRight < 0) {
3138 if (laneOffset != 0) {
3141 updateGaps(neighLeaders, neighRight, oldCenter, gapFactor, surplusGapRight, surplusGapLeft,
true);
3142 updateGaps(neighFollowers, neighRight, oldCenter, gapFactor, surplusGapRight, surplusGapLeft,
true, netOverlap);
3144#ifdef DEBUG_KEEP_LATGAP
3146 std::cout <<
" minGapLat: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n"
3156 if (stayInLane || laneOffset == 1) {
3159 surplusGapRight =
MIN2(surplusGapRight,
MAX2(0.0, halfLaneWidth + posLat - halfWidth));
3160 physicalGapRight =
MIN2(physicalGapRight,
MAX2(0.0, halfLaneWidth + posLat - halfWidth));
3162 if (stayInLane || laneOffset == -1) {
3165 surplusGapLeft =
MIN2(surplusGapLeft,
MAX2(0.0, halfLaneWidth - posLat - halfWidth));
3166 physicalGapLeft =
MIN2(physicalGapLeft,
MAX2(0.0, halfLaneWidth - posLat - halfWidth));
3168#ifdef DEBUG_KEEP_LATGAP
3170 std::cout <<
" stayInLane: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
3174 if (surplusGapRight + surplusGapLeft < 0) {
3179 const double equalDeficit = 0.5 * (surplusGapLeft + surplusGapRight);
3180 if (surplusGapRight < surplusGapLeft) {
3182 const double delta =
MIN2(equalDeficit - surplusGapRight, physicalGapLeft);
3184 maneuverDist = delta;
3185#ifdef DEBUG_KEEP_LATGAP
3187 std::cout <<
" insufficient latSpace, move left: delta=" << delta <<
"\n";
3192 const double delta =
MIN2(equalDeficit - surplusGapLeft, physicalGapRight);
3194 maneuverDist = -delta;
3195#ifdef DEBUG_KEEP_LATGAP
3197 std::cout <<
" insufficient latSpace, move right: delta=" << delta <<
"\n";
3203 latDist =
MAX2(
MIN2(latDist, surplusGapLeft), -surplusGapRight);
3204 maneuverDist =
MAX2(
MIN2(maneuverDist, surplusGapLeft), -surplusGapRight);
3205 if ((state &
LCA_KEEPRIGHT) != 0 && maneuverDist != oldManeuverDist) {
3207 latDist = oldLatDist;
3208 maneuverDist = oldManeuverDist;
3210#ifdef DEBUG_KEEP_LATGAP
3212 std::cout <<
" adapted latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
" (old=" << oldLatDist <<
")\n";
3227#ifdef DEBUG_KEEP_LATGAP
3229 std::cout <<
" traci influenced latDist=" << latDist <<
"\n";
3235 const bool traciChange = ((state | traciState) &
LCA_TRACI) != 0;
3236 if (nonSublaneChange && !traciChange) {
3238#ifdef DEBUG_KEEP_LATGAP
3240 std::cout <<
" wanted changeToLeft oldLatDist=" << oldLatDist <<
", blocked latGap changeToRight\n";
3243 latDist = oldLatDist;
3246#ifdef DEBUG_KEEP_LATGAP
3248 std::cout <<
" wanted changeToRight oldLatDist=" << oldLatDist <<
", blocked latGap changeToLeft\n";
3251 latDist = oldLatDist;
3261#ifdef DEBUG_KEEP_LATGAP
3263 std::cout <<
" latDistUpdated=" << latDist <<
" oldLatDist=" << oldLatDist <<
"\n";
3266 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset, leaders, followers, blockers, neighLeaders, neighFollowers, neighBlockers,
nullptr,
nullptr, nonSublaneChange);
3269 state = (state & ~LCA_STAY);
3280#if defined(DEBUG_KEEP_LATGAP) || defined(DEBUG_STATE)
3282 std::cout <<
" latDist2=" << latDist
3296 double& surplusGapRight,
double& surplusGapLeft,
3297 bool saveMinGap,
double netOverlap,
3299 std::vector<CLeaderDist>* collectBlockers) {
3301 const double halfWidth =
getWidth() * 0.5 + NUMERICAL_EPS;
3304 if (others[i].first != 0 && others[i].second <= 0
3306 && (netOverlap == 0 || others[i].second + others[i].first->getVehicleType().getMinGap() < netOverlap)) {
3310 double foeRight, foeLeft;
3312 const double foeCenter = foeRight + 0.5 * res;
3313 const double gap =
MIN2(fabs(foeRight - oldCenter), fabs(foeLeft - oldCenter)) - halfWidth;
3316 const double currentMinGap = desiredMinGap * gapFactor;
3327#if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP)
3329 std::cout <<
" updateGaps"
3331 <<
" foe=" << foe->
getID()
3332 <<
" foeRight=" << foeRight
3333 <<
" foeLeft=" << foeLeft
3334 <<
" oldCenter=" << oldCenter
3335 <<
" gap=" << others[i].second
3336 <<
" latgap=" << gap
3337 <<
" currentMinGap=" << currentMinGap
3338 <<
" surplusGapRight=" << surplusGapRight
3339 <<
" surplusGapLeft=" << surplusGapLeft
3347 if (foeCenter < oldCenter) {
3349 surplusGapRight =
MIN3(surplusGapRight, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
3352 surplusGapLeft =
MIN3(surplusGapLeft, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
3355 if (foeCenter < oldCenter) {
3356#if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP)
3358 std::cout <<
" new minimum rightGap=" << gap <<
"\n";
3363#if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP)
3365 std::cout <<
" new minimum leftGap=" << gap <<
"\n";
3371 if (collectBlockers !=
nullptr) {
3373 if ((foeCenter < oldCenter && latDist < 0 && gap < (desiredMinGap - latDist))
3374 || (foeCenter > oldCenter && latDist > 0 && gap < (desiredMinGap + latDist))) {
3375 collectBlockers->push_back(others[i]);
3392 int currentDirection =
mySpeedLat >= 0 ? 1 : -1;
3393 int directionWish = latDist >= 0 ? 1 : -1;
3400 maxSpeedLat =
MIN2(maxSpeedLat, speedBound);
3404 maxSpeedLat =
MAX2(maxSpeedLat, speedBound);
3410#ifdef DEBUG_MANEUVER
3414 <<
" computeSpeedLat()"
3415 <<
" latDist=" << latDist
3416 <<
" maneuverDist=" << maneuverDist
3417 <<
" urgent=" << urgent
3419 <<
" currentDirection=" << currentDirection
3420 <<
" directionWish=" << directionWish
3422 <<
" maxSpeedLat=" << maxSpeedLat
3428 if (directionWish == 1) {
3442 if (maneuverDist * latDist > 0) {
3443 maneuverDist = fullLatDist;
3446#ifdef DEBUG_MANEUVER
3450 <<
" fullLatDist=" << fullLatDist
3451 <<
" speedAccel=" << speedAccel
3452 <<
" speedDecel=" << speedDecel
3453 <<
" speedBound=" << speedBound
3457 if (speedDecel * speedAccel <= 0 && (
3459 (latDist >= 0 && speedAccel >= speedBound && speedBound >= speedDecel)
3460 || (latDist <= 0 && speedAccel <= speedBound && speedBound <= speedDecel))) {
3462#ifdef DEBUG_MANEUVER
3464 std::cout <<
" computeSpeedLat a)\n";
3471#ifdef DEBUG_MANEUVER
3473 std::cout <<
" computeSpeedLat b)\n";
3480 if ((fabs(minDistAccel) < fabs(fullLatDist)) || (fabs(minDistAccel - fullLatDist) < NUMERICAL_EPS)) {
3481#ifdef DEBUG_MANEUVER
3483 std::cout <<
" computeSpeedLat c)\n";
3488#ifdef DEBUG_MANEUVER
3490 std::cout <<
" minDistAccel=" << minDistAccel <<
"\n";
3495 if ((fabs(minDistCurrent) < fabs(fullLatDist)) || (fabs(minDistCurrent - fullLatDist) < NUMERICAL_EPS)) {
3496#ifdef DEBUG_MANEUVER
3498 std::cout <<
" computeSpeedLat d)\n";
3505#ifdef DEBUG_MANEUVER
3507 std::cout <<
" computeSpeedLat e)\n";
3519#ifdef DEBUG_MANEUVER
3521 std::cout <<
" rightDanger speedLat=" << speedLat <<
"\n";
3526#ifdef DEBUG_MANEUVER
3528 std::cout <<
" leftDanger speedLat=" << speedLat <<
"\n";
3543 const bool indirect = turnInfo.second ==
nullptr ? false : turnInfo.second->isIndirect();
3576 double maneuverDist) {
3579 double secondsToLeaveLane;
3589#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3605 double nextLeftSpace;
3606 if (nextActionStepSpeed > 0.) {
3621#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3625 <<
" avoidArrivalSpeed=" << avoidArrivalSpeed
3628 <<
"\n nextLeftSpace=" << nextLeftSpace
3629 <<
" nextActionStepSpeed=" << nextActionStepSpeed
3630 <<
" nextActionStepRemainingSeconds=" << secondsToLeaveLane - timeTillActionStep
3640#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3644 <<
" secondsToLeave=" << secondsToLeaveLane
3666 const double vehWidth =
getWidth();
3668 const double leftVehSide = rightVehSide + vehWidth;
3669 const double rightVehSideDest = rightVehSide + latDist;
3670 const double leftVehSideDest = leftVehSide + latDist;
3671#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3673 std::cout <<
" commitFollowSpeed"
3674 <<
" latDist=" << latDist
3675 <<
" foeOffset=" << foeOffset
3676 <<
" vehRight=" << rightVehSide
3677 <<
" vehLeft=" << leftVehSide
3678 <<
" destRight=" << rightVehSideDest
3679 <<
" destLeft=" << leftVehSideDest
3685 if (vehDist.first != 0) {
3686 const MSVehicle* leader = vehDist.first;
3688 double foeRight, foeLeft;
3690#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3692 std::cout <<
" foe=" << vehDist.first->getID()
3693 <<
" gap=" << vehDist.second
3695 <<
" foeRight=" << foeRight
3696 <<
" foeLeft=" << foeLeft
3697 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
3698 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
3702 if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
3706 speed =
MIN2(speed, vSafe);
3707#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3709 std::cout <<
" case1 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3712 }
else if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)) {
3717 speed =
MIN2(speed, vSafe);
3718#if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED)
3720 std::cout <<
" case2 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3740 return myOppositeParam <= 0 ? std::numeric_limits<double>::max() : 1 /
myOppositeParam;
3799 }
else if (key ==
"speedGainProbabilityRight") {
3801 }
else if (key ==
"speedGainProbabilityLeft") {
3803 }
else if (key ==
"keepRightProbability") {
3805 }
else if (key ==
"lookAheadSpeed") {
3807 }
else if (key ==
"sigmaState") {
3810 }
else if (key ==
"speedGainRP") {
3812 }
else if (key ==
"speedGainLP") {
3814 }
else if (key ==
"keepRightP") {
3884 }
else if (key ==
"speedGainProbabilityRight") {
3886 }
else if (key ==
"speedGainProbabilityLeft") {
3888 }
else if (key ==
"keepRightProbability") {
3890 }
else if (key ==
"lookAheadSpeed") {
3892 }
else if (key ==
"sigmaState") {
3906 const std::pair<MSVehicle*, double>& leader,
3907 const std::pair<MSVehicle*, double>& follower,
3908 const std::pair<MSVehicle*, double>& neighLead,
3909 const std::pair<MSVehicle*, double>& neighFollow,
3911 const std::vector<MSVehicle::LaneQ>& preb,
3917#ifdef DEBUG_WANTSCHANGE
3919 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME
3923 <<
" neigh=" << neighLane.
getID()
3927 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3941 double maneuverDist;
3944 leaders, followers, blockers,
3945 neighLeaders, neighFollowers, neighBlockers,
3947 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
3951 result &= ~LCA_SUBLANE;
3952 result |=
getLCA(result, latDist);
3954#if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE)
3959 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3960 << ((result &
LCA_URGENT) ?
" (urgent)" :
"")
3966 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
4018 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" bgap=" << brakeGap <<
" maneuverDist=" << maneuverDist
#define HELP_DECEL_FACTOR
#define LOOK_AHEAD_MIN_SPEED
#define LCA_RIGHT_IMPATIENCE
#define REACT_TO_STOPPED_DISTANCE
#define RELGAIN_NORMALIZATION_MIN_SPEED
#define CUT_IN_LEFT_SPEED_THRESHOLD
#define MAX_ONRAMP_LENGTH
#define LOOK_AHEAD_SPEED_MEMORY
#define ARRIVALPOS_LAT_THRESHOLD
#define SPEEDGAIN_MEMORY_FACTOR
#define LOOK_AHEAD_MIN_SPEED
#define SPEEDGAIN_DECAY_FACTOR
#define LATGAP_SPEED_THRESHOLD
#define GAIN_PERCEPTION_THRESHOLD
#define LATGAP_SPEED_THRESHOLD2
std::pair< const MSVehicle *, double > CLeaderDist
std::pair< const MSPerson *, double > PersonDist
LatAlignmentDefinition
Possible ways to choose the lateral alignment, i.e., how vehicles align themselves within their lane.
@ RIGHT
drive on the right side
@ GIVEN
The alignment as offset is given.
@ DEFAULT
No information given; use default.
@ LEFT
drive on the left side
@ ARBITRARY
maintain the current alignment
@ NICE
align with the closest sublane border
@ COMPACT
align with the rightmost sublane that allows keeping the current speed
@ CENTER
drive in the middle
@ 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.
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ 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_MAXDISTLATSTANDING
@ SUMO_ATTR_LCA_IMPATIENCE
@ SUMO_ATTR_LCA_COOPERATIVE_ROUNDABOUT
@ SUMO_ATTR_LCA_SPEEDGAIN_LOOKAHEAD
@ SUMO_ATTR_LCA_MAXSPEEDLATFACTOR
@ SUMO_ATTR_LCA_MAXSPEEDLATSTANDING
@ SUMO_ATTR_LCA_KEEPRIGHT_PARAM
@ SUMO_ATTR_LCA_COOPERATIVE_PARAM
@ SUMO_ATTR_LCA_OPPOSITE_PARAM
@ SUMO_ATTR_LCA_SPEEDGAIN_REMAIN_TIME
@ SUMO_ATTR_LCA_OVERTAKE_DELTASPEED_FACTOR
@ SUMO_ATTR_LCA_SUBLANE_PARAM
@ SUMO_ATTR_LCA_ACCEL_LAT
@ SUMO_ATTR_LCA_STRATEGIC_PARAM
@ SUMO_ATTR_LCA_KEEPRIGHT_ACCEPTANCE_TIME
@ 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 getForwardPos() const
get vehicle position relative to the forward direction lane
bool hasBlueLight() const
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()
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
double myLastLateralGapRight
double myCommittedSpeed
the speed when committing to a change maneuver
virtual LatAlignmentDefinition getDesiredAlignment() const
static const double NO_NEIGHBOR
double myMaxDistLatStanding
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
void addLCSpeedAdvice(const double vSafe, bool ownAdvice=true)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
int & getCanceledState(const int dir)
double myMaxSpeedLatFactor
const LaneChangeModel myModel
the type of this model
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
std::vector< std::pair< double, bool > > myLCAccelerationAdvices
double getMaxSpeedLat2() const
return the max of maxSpeedLat and lcMaxSpeedLatStanding
const MSCFModel & getCarFollowModel() const
The vehicle's car following model.
double mySpeedLat
the current lateral speed
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 avoidOvertakeRight() const
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)
double getLength() const
Returns the vehicle's length.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
const MSRoute & getRoute() const
Returns the current route.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
The car-following model abstraction.
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
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 minNextSpeedEmergency(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed after emergency braking, given the current speed (depends on the numerical ...
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 physically 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].
@ LANE_CHANGE
the return value is used for lane change calculations
virtual double getSecureGap(const MSVehicle *const veh, 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)
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 followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0, const CalcReason usage=CalcReason::CURRENT) const =0
Computes the vehicle's follow speed (no dawdling)
double stopSpeed(const MSVehicle *const veh, const double speed, double gap, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
A road/street connecting two junctions.
const std::set< MSTransportable *, ComparatorNumericalIdLess > & getPersons() const
Returns this edge's persons set.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
bool canChangeToOpposite() const
whether this edge allows changing to the opposite direction edge
bool isInternal() const
return whether this edge is an internal edge
double getWidth() const
Returns the edges's width (sum over all lanes)
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 bool canSaveBlockerLength(const MSVehicle &veh, double requested, double leftSpace)
static double getSpeedPreservingSecureGap(const MSVehicle &leader, const MSVehicle &follower, double currentGap, double leaderPlannedSpeed)
static double getRoundaboutDistBonus(const MSVehicle &veh, double bonusParam, const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, const MSVehicle::LaneQ &best)
static bool updateBlockerLength(const MSVehicle &veh, MSVehicle *blocker, int lcaCounter, double leftSpace, bool reliefConnection, double &leadingBlockerLength)
static bool divergentRoute(const MSVehicle &v1, const MSVehicle &v2)
return whether the vehicles are on the same junction but on divergent paths
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 _patchSpeed(double min, const double wanted, double max, const MSCFModel &cfModel)
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 maneuver 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 prepareStep() override
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 getLeftBorder(bool checkOpposite=true) const
return current edge width optionally extended by opposite direction lane width
double myChangeProbThresholdRight
double informLeader(int blocked, int dir, const CLeaderDist &neighLead, double remainingSeconds)
MSLCM_SL2015(MSVehicle &v)
int computeSublaneShift(const MSEdge *prevEdge, const MSEdge *curEdge)
compute shift so that prevSublane + shift = newSublane
double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel) override
Called to adapt the speed in order to allow a lane change. It uses information on LC-related desired ...
double getSafetyFactor() const override
return factor for modifying the safety constraints of the car-following model
double myCooperativeSpeed
double computeSpeedLat(double latDist, double &maneuverDist, bool urgent) const override
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
std::vector< double > myExpectedSublaneSpeeds
expected travel speeds on all sublanes on the current edge(!)
double getWidth() const
return the width of this vehicle (padded for numerical stability)
bool myCanChangeFully
whether the current lane changing maneuver can be finished in a single step
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &follower, 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) override
Called to examine whether the vehicle wants to change using the given laneOffset (this is a wrapper a...
bool outsideEdge() const
whether the ego vehicle is driving outside edgebounds
bool myDontBrake
flag to prevent speed adaptation by slowing down
std::string getParameter(const std::string &key) const override
try to retrieve the given parameter from this device. Throw exception for unsupported key
bool wantsKeepRight(double keepRightProb) const
check against thresholds
double forecastAverageSpeed(double vSafe, double vMax, double gap, double vLeader) const
estimate average speed over mySpeedGainLookahead time
void updateCFRelated(const MSLeaderDistanceInfo &vehicles, double foeOffset, bool leaders)
find leaders/followers that are already in a car-following relationship with ego
bool debugVehicle() const override
whether the current vehicles shall be debugged
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) override
Called to examine whether the vehicle wants to change with the given laneOffset (using the sublane mo...
LatAlignmentDefinition getDesiredAlignment() const override
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 tieBrakeLeader(const MSVehicle *veh) const
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
CLeaderDist getLongest(const MSLeaderDistanceInfo &ldi) const
get the longest vehicle in the given info
double myCooperativeParam
double getNeighRight(const MSLane &neighLane) const
return the right offset of the neighboring lane relative to the current edge
double computeSpeedGain(double latDistSublane, double defaultNextSpeed) const
compute speedGain when moving by the given amount
double emergencySpeedLat(double speedLat) const
avoid unsafe lateral speed (overruling lcAccelLat)
double myKeepRightAcceptanceTime
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
virtual void updateSafeLatDist(const double travelledLatDist) override
Updates the value of safe lateral distances (mySafeLatDistLeft and mySafeLatDistRight) during maneuve...
const MSEdge * myLastEdge
expected travel speeds on all sublanes on the current edge(!)
double getOppositeSafetyFactor() const override
return factor for modifying the safety constraints for opposite-diretction overtaking of the car-foll...
int checkStrategicChange(int ret, const MSLane &neighLane, int laneOffset, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, const MSVehicle::LaneQ &best, int bestLaneOffset, bool changeToBest, double currentDist, double neighDist, double laDist, double roundaboutBonus, double latLaneDist, bool checkOpposite, double &latDist)
compute strategic lane change actions TODO: Better documentation, refs #2
StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const override
decide in which direction to move in case both directions are desirable
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
void msg(const CLeaderDist &cld, double speed, int state)
send a speed recommendation to the given vehicle
double mySpeedGainRemainTime
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 getVehicleCenter() const
return vehicle position relative to the current edge (extend by another virtual lane for opposite-dir...
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
bool preventSliding(double maneuverDist) const
bool isBidi(const MSLane *lane) const
check whether lane is an upcoming bidi lane
bool mustOvertakeStopped(const MSLane &neighLane, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLead, double posOnLane, double neighDist, bool right, double latLaneDist, double ¤tDist, double &latDist)
void * inform(void *info, MSVehicle *sender) override
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
void setParameter(const std::string &key, const std::string &value) override
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
bool saveBlockerLength(double length, double foeLeftSpace) override
reserve space at the end of the lane to avoid dead locks
double myOvertakeDeltaSpeedFactor
double myTurnAlignmentDist
double myLeadingBlockerLength
void setOwnState(const int state) override
int checkBlockingVehicles(const MSVehicle *ego, const MSLeaderDistanceInfo &vehicles, int laneOffset, double latDist, double foeOffset, bool leaders, double &safeLatGapRight, double &safeLatGapLeft, std::vector< CLeaderDist > *collectBlockers=0) const
check whether any of the vehicles overlaps with ego
void informFollowers(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds, double plannedSpeed)
call informFollower for multiple followers
double mySpeedGainLookahead
double mySpeedLossProbThreshold
void resetState() override
double mySpeedGainProbabilityLeft
a value for tracking the probability that a change to the left is beneficial
static LaneChangeAction getLCA(int state, double latDist)
compute lane change action from desired lateral distance
double myChangeProbThresholdLeft
void updateExpectedSublaneSpeeds(const MSLeaderDistanceInfo &ahead, int sublaneOffset, int laneIndex) override
update expected speeds for each sublane of the current edge
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
double getExtraReservation(int bestLaneOffset) const override
reserve extra space for unseen blockers when more tnan one lane change is required
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.
std::pair< const MSPerson *, double > nextBlocking(double minPos, double minRight, double maxLeft, double stopTime=0, bool bidi=false) const
This is just a wrapper around MSPModel::nextBlocking. You should always check using hasPedestrians be...
MSLane * getParallelLane(int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
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.
MSLane * getOpposite() const
return the neighboring opposite direction lane for lane changing or nullptr
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
MSLane * getParallelOpposite() const
return the opposite direction lane of this lanes edge or nullptr
MSEdge & getEdge() const
Returns the lane's edge.
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
double getWidth() const
Returns the lane's width.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
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
void getSubLanes(const MSVehicle *veh, double latOffset, int &rightmost, int &leftmost) 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)
double getLeftSideOnEdge(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.
const std::pair< double, const MSLink * > & getNextTurn()
Get the distance and direction of the next upcoming turn for the vehicle (within its look-ahead range...
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...
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
int getBestLaneOffset() const
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
const MSLane * getLane() const
Returns the lane the vehicle is on.
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
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.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getPositionOnLane() const
Get the vehicle's position along the lane.
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane
bool hasInfluencer() const
whether the vehicle is individually influenced (via TraCI or special parameters)
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 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.
const LatAlignmentDefinition & getPreferredLateralAlignment() const
Get vehicle's preferred lateral alignment procedure.
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].
double getPreferredLateralAlignmentOffset() const
Get vehicle's preferred lateral alignment offset (in m from center line)
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
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
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
MSLane * lane
The described lane.
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.