45 #define LOOK_FORWARD_SPEED_DIVIDER (double)14. 47 #define MAGIC_OFFSET 1. 52 #define LOOK_FORWARD_RIGHT (double)10. 53 #define LOOK_FORWARD_LEFT (double)20. 55 #define JAM_FACTOR (double)1. 58 #define LCA_RIGHT_IMPATIENCE (double)-1. 59 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27. 60 #define MAX_ONRAMP_LENGTH (double)200. 62 #define LOOK_AHEAD_MIN_SPEED 0.0 63 #define LOOK_AHEAD_SPEED_MEMORY 0.9 65 #define HELP_DECEL_FACTOR (double)1.0 67 #define HELP_OVERTAKE (double)(10.0 / 3.6) 68 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 70 #define KEEP_RIGHT_HEADWAY (double)2.0 72 #define URGENCY (double)2.0 74 #define ROUNDABOUT_DIST_BONUS (double)100.0 76 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 77 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 79 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 81 #define TURN_LANE_DIST (double)200.0 // the distance at which a lane leading elsewhere is considered to be a turn-lane that must be avoided 82 #define GAIN_PERCEPTION_THRESHOLD 0.05 // the minimum relative speed gain which affects the behavior 84 #define SPEED_GAIN_MIN_SECONDS 20.0 86 #define ARRIVALPOS_LAT_THRESHOLD 100.0 89 #define LATGAP_SPEED_THRESHOLD (50 / 3.6) 92 #define LATGAP_SPEED_THRESHOLD2 (50 / 3.6) 95 #define SPEEDGAIN_DECAY_FACTOR 0.5 97 #define SPEEDGAIN_MEMORY_FACTOR 0.5 101 #define DEBUG_COND (myVehicle.isSelected()) 113 mySpeedGainProbabilityRight(0),
114 mySpeedGainProbabilityLeft(0),
115 myKeepRightProbability(0),
116 myLeadingBlockerLength(0),
120 myCanChangeFully(true),
166 const std::vector<MSVehicle::LaneQ>& preb,
169 double& latDist,
int& blocked) {
172 const std::string changeType = laneOffset == -1 ?
"right" : (laneOffset == 1 ?
"left" :
"current");
183 <<
" considerChangeTo=" << changeType
189 leaders, followers, blockers,
190 neighLeaders, neighFollowers, neighBlockers,
192 lastBlocked, firstBlocked, latDist, blocked);
194 result =
keepLatGap(result, leaders, followers, blockers,
195 neighLeaders, neighFollowers, neighBlockers,
196 neighLane, laneOffset, latDist, blocked);
198 result |=
getLCA(result, latDist);
201 double latDistTmp = latDist;
211 <<
" latDist=" << latDist
219 <<
" wantsNoChangeTo=" << changeType
248 std::cout <<
" myCanChangeFully=true\n";
258 const double newSpeed =
_patchSpeed(min, wanted, max, cfModel);
260 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
266 <<
" wanted=" << wanted
292 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
294 return MAX2(min, safe);
298 double nVSafe = wanted;
300 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
302 if (v >= min && v <= max) {
303 nVSafe =
MIN2(v, nVSafe);
311 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
315 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
336 return (max + wanted) / (double) 2.0;
343 return (min + wanted) / (double) 2.0;
349 return (max + wanted) / (double) 2.0;
393 return (max + wanted) / (double) 2.0;
415 if (pinfo->first >= 0) {
423 <<
" informedBy=" << sender->
getID()
424 <<
" info=" << pinfo->second
425 <<
" vSafe=" << pinfo->first
435 assert(cld.first != 0);
444 double remainingSeconds) {
447 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
450 plannedSpeed =
MIN2(plannedSpeed, v);
454 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
458 assert(neighLead.first != 0);
460 if (
gDebugFlag2) std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 463 const double dv = plannedSpeed - nv->
getSpeed();
464 const double overtakeDist = (neighLead.second
476 || dv * remainingSeconds < overtakeDist) {
490 <<
" cannot overtake leader nv=" << nv->
getID()
492 <<
" remainingSeconds=" << remainingSeconds
493 <<
" targetSpeed=" << targetSpeed
494 <<
" nextSpeed=" << nextSpeed
503 <<
" cannot overtake fast leader nv=" << nv->
getID()
505 <<
" remainingSeconds=" << remainingSeconds
506 <<
" targetSpeed=" << targetSpeed
515 <<
" wants to overtake leader nv=" << nv->
getID()
517 <<
" remainingSeconds=" << remainingSeconds
518 <<
" currentGap=" << neighLead.second
520 <<
" overtakeDist=" << overtakeDist
529 }
else if (neighLead.first != 0) {
538 std::cout <<
" not blocked by leader nv=" << nv->
getID()
540 <<
" gap=" << neighLead.second
541 <<
" nextGap=" << neighLead.second - dv
543 <<
" targetSpeed=" << targetSpeed
546 return MIN2(targetSpeed, plannedSpeed);
558 double remainingSeconds,
559 double plannedSpeed) {
561 assert(neighFollow.first != 0);
563 if (
gDebugFlag2) std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 569 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
571 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
589 const double neighNewSpeed1s =
MAX2(0., nv->
getSpeed() - helpDecel);
590 const double dv = plannedSpeed - neighNewSpeed1s;
592 const double decelGap = neighFollow.second + dv;
597 <<
" egoNV=" << plannedSpeed
598 <<
" nvNewSpeed=" << neighNewSpeed
599 <<
" nvNewSpeed1s=" << neighNewSpeed1s
600 <<
" deltaGap=" << dv
601 <<
" decelGap=" << decelGap
602 <<
" secGap=" << secureGap
605 if (decelGap > 0 && decelGap >= secureGap) {
619 std::cout <<
" wants to cut in before nv=" << nv->
getID()
620 <<
" vsafe1=" << vsafe1
621 <<
" vsafe=" << vsafe
625 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap +
POSITION_EPS)) {
629 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
635 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
649 std::cout <<
" wants right follower to slow down a bit\n";
653 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
661 const double overtakeDist = (neighFollow.second
667 const double needDV = overtakeDist / remainingSeconds;
674 <<
" wants to be overtaken by=" << nv->
getID()
675 <<
" overtakeDist=" << overtakeDist
677 <<
" vhelp=" << vhelp
678 <<
" needDV=" << needDV
683 }
else if (neighFollow.first != 0) {
692 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
699 const std::vector<CLeaderDist>& blockers,
700 double remainingSeconds) {
707 plannedSpeed =
MIN2(plannedSpeed, safe);
710 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
711 plannedSpeed =
MIN2(plannedSpeed,
informLeader(blocked, dir, *it, remainingSeconds));
719 const std::vector<CLeaderDist>& blockers,
720 double remainingSeconds,
721 double plannedSpeed) {
722 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
723 informFollower(blocked, dir, *it, remainingSeconds, plannedSpeed);
755 std::vector<double> newExpectedSpeeds;
760 const std::vector<MSLane*>& lanes = currEdge->
getLanes();
761 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
763 for (
int i = 0; i < subLanes; ++i) {
764 newExpectedSpeeds.push_back((*it_lane)->getVehicleMaxSpeed(&
myVehicle));
774 const int newI = i + subLaneShift;
775 if (newI > 0 && newI < (
int)newExpectedSpeeds.size()) {
793 const std::vector<MSLane*>& lanes = prevEdge->
getLanes();
794 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
795 const MSLane* lane = *it_lane;
796 for (MSLinkCont::const_iterator it_link = lane->
getLinkCont().begin(); it_link != lane->
getLinkCont().end(); ++it_link) {
797 if (&((*it_link)->getLane()->getEdge()) == curEdge) {
799 const MSLane* target = (*it_link)->getLane();
800 const std::vector<MSLane*>& lanes2 = curEdge->
getLanes();
801 for (std::vector<MSLane*>::const_iterator it_lane2 = lanes2.begin(); it_lane2 != lanes2.end(); ++it_lane2) {
802 const MSLane* lane2 = *it_lane2;
803 if (lane2 == target) {
804 return prevShift + curShift;
860 const std::vector<MSVehicle::LaneQ>& preb,
863 double& latDist,
int& blocked) {
868 int bestLaneOffset = 0;
869 double currentDist = 0;
870 double neighDist = 0;
877 for (
int p = 0; p < (int) preb.size(); ++p) {
878 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
879 assert(p + laneOffset < (
int)preb.size());
881 neigh = preb[p + laneOffset];
882 currentDist = curr.
length;
884 bestLaneOffset = curr.bestLaneOffset;
886 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
890 <<
" bestLaneOffsetOld=" << bestLaneOffset
891 <<
" bestLaneOffsetNew=" << laneOffset
894 bestLaneOffset = laneOffset;
901 const bool right = (laneOffset == -1);
902 const bool left = (laneOffset == 1);
906 const bool changeToBest = (right && bestLaneOffset < 0) || (left && bestLaneOffset > 0) || (laneOffset == 0 && bestLaneOffset == 0);
914 const double halfVehWidth = 0.5 *
getWidth();
916 double leftLimit = halfCurrentLaneWidth - halfVehWidth - latPos;
917 double rightLimit = -halfCurrentLaneWidth + halfVehWidth - latPos;
918 double latLaneDist = 0;
919 if (laneOffset == -1) {
920 latLaneDist = rightLimit -
getWidth();
922 }
else if (laneOffset == 1) {
923 latLaneDist = leftLimit +
getWidth();
948 <<
" leaders=" << leaders.
toString()
949 <<
" followers=" << followers.
toString()
950 <<
" blockers=" << blockers.
toString()
951 <<
" neighLeaders=" << neighLeaders.
toString()
952 <<
" neighFollowers=" << neighFollowers.
toString()
953 <<
" neighBlockers=" << neighBlockers.
toString()
954 <<
" changeToBest=" << changeToBest
955 <<
" latLaneDist=" << latLaneDist
956 <<
" leftLimit=" << leftLimit
957 <<
" rightLimit=" << rightLimit
964 if (lastBlocked != firstBlocked) {
1021 int roundaboutEdgesAhead = 0;
1023 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
1024 roundaboutEdgesAhead += 1;
1025 }
else if (roundaboutEdgesAhead > 0) {
1030 int roundaboutEdgesAheadNeigh = 0;
1032 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
1033 roundaboutEdgesAheadNeigh += 1;
1034 }
else if (roundaboutEdgesAheadNeigh > 0) {
1039 if (roundaboutEdgesAhead > 1) {
1043 if (roundaboutEdgesAhead > 0) {
1045 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1049 if (laneOffset != 0) {
1062 roundaboutEdgesAhead,
1067 if ((ret &
LCA_STAY) != 0 && latDist == 0) {
1072 if (changeToBest &&
abs(bestLaneOffset) > 1
1078 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1086 if (*firstBlocked != neighLeadLongest) {
1089 std::vector<CLeaderDist> collectLeadBlockers;
1090 std::vector<CLeaderDist> collectFollowBlockers;
1091 int blockedFully = 0;
1095 leaders, followers, blockers,
1096 neighLeaders, neighFollowers, neighBlockers, &collectLeadBlockers, &collectFollowBlockers,
1097 false, gapFactor, &blockedFully);
1099 const double absLaneOffset = fabs(bestLaneOffset != 0 ? bestLaneOffset : latDist /
SUMO_const_laneWidth);
1100 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1103 const double plannedSpeed =
informLeaders(blocked, myLca, collectLeadBlockers, remainingSeconds);
1105 if (plannedSpeed >= 0) {
1107 informFollowers(blocked, myLca, collectFollowBlockers, remainingSeconds, plannedSpeed);
1109 if (plannedSpeed > 0) {
1110 commitManoeuvre(blocked, blockedFully, leaders, neighLeaders, neighLane);
1117 <<
" blockedFully=" << blockedFully
1118 <<
" remainingSeconds=" << remainingSeconds
1119 <<
" plannedSpeed=" << plannedSpeed
1126 if (roundaboutEdgesAhead > 1) {
1135 if ((ret & LCA_STAY) == 0) {
1136 latDist = latLaneDist;
1138 leaders, followers, blockers,
1139 neighLeaders, neighFollowers, neighBlockers);
1154 const double inconvenience = (latLaneDist < 0
1175 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1177 << (((
myOwnState & myLcaCounter) != 0) ?
" (counter)" :
"")
1185 leaders, followers, blockers,
1186 neighLeaders, neighFollowers, neighBlockers);
1210 const double vehWidth =
getWidth();
1212 const double leftVehSide = rightVehSide + vehWidth;
1216 int leftmostOnEdge = (int)sublaneSides.size() - 1;
1217 while (leftmostOnEdge > 0 && sublaneSides[leftmostOnEdge] > leftVehSide) {
1220 int rightmostOnEdge = leftmostOnEdge;
1221 while (rightmostOnEdge > 0 && sublaneSides[rightmostOnEdge] > rightVehSide +
NUMERICAL_EPS) {
1224 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1227 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1233 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1236 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1244 const double leftMax =
MAX2(
1247 assert(leftMax <= edge.
getWidth());
1248 int sublaneCompact =
MAX2(iMin, rightmostOnEdge - 1);
1251 <<
" checking sublanes rightmostOnEdge=" << rightmostOnEdge
1252 <<
" leftmostOnEdge=" << leftmostOnEdge
1254 <<
" leftMax=" << leftMax
1255 <<
" sublaneCompact=" << sublaneCompact
1257 for (
int i = iMin; i < (int)sublaneSides.size(); ++i) {
1258 if (sublaneSides[i] + vehWidth < leftMax) {
1264 while (vMin > 0 && j < (
int)sublaneSides.size() && sublaneSides[j] < sublaneSides[i] + vehWidth) {
1270 const double currentLatDist = sublaneSides[i] - rightVehSide;
1272 if (relativeGain > maxGain) {
1273 maxGain = relativeGain;
1276 latDist = currentLatDist;
1278 std::cout <<
" i=" << i <<
" newLatDist=" << latDist <<
" relGain=" << relativeGain <<
"\n";
1283 if (currentLatDist > 0
1288 latDist = currentLatDist;
1292 std::cout <<
" i=" << i <<
" rightmostOnEdge=" << rightmostOnEdge <<
" vMin=" << vMin <<
" relGain=" << relativeGain <<
" sublaneCompact=" << sublaneCompact <<
" curLatDist=" << currentLatDist <<
"\n";
1295 maxGainRight =
MAX2(maxGainRight, relativeGain);
1297 maxGainLeft =
MAX2(maxGainLeft, relativeGain);
1299 const double subAlignDist = sublaneSides[i] - rightVehSide;
1300 if (fabs(subAlignDist) < fabs(latDistNice)) {
1301 latDistNice = subAlignDist;
1303 <<
" nicest sublane=" << i
1304 <<
" side=" << sublaneSides[i]
1305 <<
" rightSide=" << rightVehSide
1306 <<
" latDistNice=" << latDistNice
1307 <<
" maxGainR=" << maxGainRight
1308 <<
" maxGainL=" << maxGainLeft
1334 && (right || (alternatives &
LCA_RIGHT) == 0)) {
1338 && (left || (alternatives &
LCA_LEFT) == 0)) {
1345 <<
" defaultNextSpeed=" << defaultNextSpeed
1346 <<
" maxGain=" << maxGain
1347 <<
" maxGainRight=" << maxGainRight
1348 <<
" maxGainLeft=" << maxGainLeft
1349 <<
" latDist=" << latDist
1350 <<
" latDistNice=" << latDistNice
1351 <<
" sublaneCompact=" << sublaneCompact
1356 if (right && maxGain >= 0 && latDist <= 0) {
1363 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1365 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1366 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1368 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1369 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1376 <<
" considering keepRight:" 1378 <<
" neighDist=" << neighDist
1380 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1382 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1383 <<
" acceptanceTime=" << acceptanceTime
1384 <<
" fullSpeedGap=" << fullSpeedGap
1385 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1386 <<
" dProb=" << deltaProb
1396 latDist = latLaneDist;
1398 leaders, followers, blockers,
1399 neighLeaders, neighFollowers, neighBlockers);
1409 <<
" neighDist=" << neighDist
1412 <<
" latDist=" << latDist
1420 int blockedFully = 0;
1422 leaders, followers, blockers,
1423 neighLeaders, neighFollowers, neighBlockers,
1424 0, 0,
false, 0, &blockedFully);
1437 <<
" latDist=" << latDist
1438 <<
" neighDist=" << neighDist
1441 <<
" stayInLane=" << stayInLane
1451 int blockedFully = 0;
1453 leaders, followers, blockers,
1454 neighLeaders, neighFollowers, neighBlockers,
1455 0, 0,
false, 0, &blockedFully);
1464 double latDistSublane = 0.;
1466 const double halfVehWidth =
getWidth() * 0.5;
1469 && bestLaneOffset == 0
1505 latDistSublane = latDistNice;
1508 latDistSublane = sublaneSides[sublaneCompact] - rightVehSide;
1519 <<
" latDist=" << latDist
1520 <<
" latDistSublane=" << latDistSublane
1521 <<
" relGainSublane=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed)
1536 && ((myOrigLatDist < 0 && latDistSublane > 0) || (
myOrigLatDist > 0 && latDistSublane < 0))) {
1539 latDist = latDistSublane;
1546 <<
" latDist=" << latDist
1551 leaders, followers, blockers,
1552 neighLeaders, neighFollowers, neighBlockers);
1592 if ((*blocked) != 0) {
1616 (*blocked)->getCarFollowModel().getMaxDecel()));
1656 <<
" potential=" << potential
1669 const MSLane* lane = lanes[laneIndex];
1671 assert(preb.size() == lanes.size());
1673 for (
int sublane = 0; sublane < (int)ahead.
numSublanes(); ++sublane) {
1674 const int edgeSublane = sublane + sublaneOffset;
1678 const MSVehicle* leader = ahead[sublane];
1690 const double deltaV = vMax - leader->
getSpeed();
1691 if (deltaV > 0 && gap / deltaV < 5) {
1700 double foeRight, foeLeft;
1704 if (leader.first != 0) {
1707 vSafe =
MIN2(vSafe, vSafePed);
1710 vSafe =
MIN2(vMax, vSafe);
1727 const double vehWidth =
getWidth();
1729 const double leftVehSide = rightVehSide + vehWidth;
1730 for (
int i = 0; i < (int)sublaneSides.size(); ++i) {
1731 if (
overlap(rightVehSide, leftVehSide, sublaneSides[i], sublaneSides[i] + res)) {
1737 return result - defaultNextSpeed;
1744 double maxLength = -1;
1746 if (ldi[i].first != 0) {
1747 const double length = ldi[i].first->getVehicleType().getLength();
1748 if (length > maxLength) {
1763 if (ldi[i].first != 0) {
1764 const double speed = ldi[i].first->getSpeed();
1765 if (speed < minSpeed) {
1783 std::vector<CLeaderDist>* collectLeadBlockers,
1784 std::vector<CLeaderDist>* collectFollowBlockers,
1785 bool keepLatGapManeuver,
1787 int* retBlockedFully) {
1789 if (!keepLatGapManeuver) {
1793 latDist =
MAX2(
MIN2(latDist, maxDist), -maxDist);
1798 if (laneOffset != 0) {
1806 const double halfWidth =
getWidth() * 0.5;
1808 double surplusGapRight =
MIN2(maxDist, center - halfWidth);
1812 if (laneOffset != 0) {
1813 updateGaps(neighLeaders, neighLane.
getRightSideOnEdge(), center, gapFactor, surplusGapRight, surplusGapLeft,
false, 0, latDist, collectLeadBlockers);
1814 updateGaps(neighFollowers, neighLane.
getRightSideOnEdge(), center, gapFactor, surplusGapRight, surplusGapLeft,
false, 0, latDist, collectFollowBlockers);
1817 std::cout <<
" checkBlocking latDist=" << latDist <<
" surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
1823 latDist =
MAX2(latDist, -surplusGapRight);
1829 latDist =
MIN2(latDist, surplusGapLeft);
1846 if (laneOffset != 0) {
1853 int blockedFully = 0;
1856 if (laneOffset != 0) {
1862 if (retBlockedFully != 0) {
1863 *retBlockedFully = blockedFully;
1870 blocked |= blockedFully;
1872 if (collectFollowBlockers != 0 && collectLeadBlockers != 0) {
1874 for (std::vector<CLeaderDist>::const_iterator it2 = collectLeadBlockers->begin(); it2 != collectLeadBlockers->end(); ++it2) {
1875 for (std::vector<CLeaderDist>::iterator it = collectFollowBlockers->begin(); it != collectFollowBlockers->end();) {
1876 if ((*it2).first == (*it).first) {
1878 std::cout <<
" removed follower " << (*it).first->getID() <<
" because it is already a leader\n";
1880 it = collectFollowBlockers->erase(it);
1894 double latDist,
double foeOffset,
bool leaders,
LaneChangeAction blockType,
1895 std::vector<CLeaderDist>* collectBlockers)
const {
1897 const double vehWidth =
getWidth();
1899 const double leftVehSide = rightVehSide + vehWidth;
1900 const double rightVehSideDest = rightVehSide + latDist;
1901 const double leftVehSideDest = leftVehSide + latDist;
1902 const double rightNoOverlap =
MIN2(rightVehSideDest, rightVehSide);
1903 const double leftNoOverlap =
MAX2(leftVehSideDest, leftVehSide);
1905 std::cout <<
" checkBlocking" 1906 <<
" latDist=" << latDist
1907 <<
" foeOffset=" << foeOffset
1908 <<
" vehRight=" << rightVehSide
1909 <<
" vehLeft=" << leftVehSide
1910 <<
" rightNoOverlap=" << rightNoOverlap
1911 <<
" leftNoOverlap=" << leftNoOverlap
1912 <<
" destRight=" << rightVehSideDest
1913 <<
" destLeft=" << leftVehSideDest
1914 <<
" leaders=" << leaders
1918 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
1920 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
1921 const MSVehicle* leader = vehDist.first;
1924 std::swap(leader, follower);
1927 double foeRight, foeLeft;
1930 std::cout <<
" foe=" << vehDist.first->getID()
1931 <<
" gap=" << vehDist.second
1933 <<
" foeRight=" << foeRight
1934 <<
" foeLeft=" << foeLeft
1935 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
1936 <<
" overlap=" <<
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft)
1937 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
1940 if (
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft)) {
1941 if (vehDist.second < 0) {
1943 std::cout <<
" overlap\n";
1946 if (collectBlockers == 0) {
1949 collectBlockers->push_back(vehDist);
1951 }
else if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
1955 const double secureGap2 = secureGap / decelFactor;
1956 if (vehDist.second < secureGap2) {
1958 std::cout <<
" blocked by " << vehDist.first->getID() <<
" gap=" << vehDist.second
1959 <<
" secGap=" << secureGap <<
" secGap2=" << secureGap2 <<
" decelFactor=" << decelFactor <<
"\n";
1961 result |= blockType;
1962 if (collectBlockers == 0) {
1965 collectBlockers->push_back(vehDist);
1967 }
else if (
gDebugFlag2 && vehDist.second < secureGap) {
1968 std::cout <<
" ignore blocker " << vehDist.first->getID() <<
" gap=" << vehDist.second
1969 <<
" secGap=" << secureGap <<
" secGap2=" << secureGap2 <<
" decelFactor=" << decelFactor <<
"\n";
1986 const double leftVehSide = rightVehSide + vehWidth;
1988 std::cout <<
" updateCFRelated foeOffset=" << foeOffset <<
" vehicles=" << vehicles.
toString() <<
"\n";
1990 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
1992 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
1993 double foeRight, foeLeft;
1997 std::cout <<
" ignoring cfrelated foe=" << vehDist.first->getID() <<
" gap=" << vehDist.second
1999 <<
" foeOffset=" << foeOffset
2000 <<
" egoR=" << rightVehSide <<
" egoL=" << leftVehSide
2001 <<
" iR=" << foeRight <<
" iL=" << foeLeft
2013 assert(right <= left);
2014 assert(right2 <= left2);
2022 if (sd1.
state == 0) {
2024 }
else if (sd2.
state == 0) {
2037 <<
" dir1=" << sd1.
dir 2041 <<
" dir2=" << sd2.
dir 2048 return (!can1 && can2 && sd1.
sameDirection(sd2)) ? sd2 : sd1;
2052 return (!can2 && can1 && sd1.
sameDirection(sd2)) ? sd1 : sd2;
2060 }
else if (sd2.
dir == 0) {
2065 assert(sd1.
dir == -1);
2066 assert(sd2.
dir == 1);
2069 }
else if (sd2.
latDist >= 0) {
2077 return can1 ? sd1 : sd2;
2100 const std::vector<MSVehicle::LaneQ>& preb,
2110 int roundaboutEdgesAhead,
2114 const bool right = (laneOffset == -1);
2115 const bool left = (laneOffset == 1);
2123 const double maxJam =
MAX2(preb[currIdx + laneOffset].occupation, preb[currIdx].occupation);
2131 <<
" laDist=" << laDist
2132 <<
" currentDist=" << currentDist
2133 <<
" usableDist=" << usableDist
2134 <<
" bestLaneOffset=" << bestLaneOffset
2135 <<
" best.length=" << best.
length 2136 <<
" maxJam=" << maxJam
2137 <<
" neighLeftPlace=" << neighLeftPlace
2141 if (laneOffset != 0 && changeToBest && bestLaneOffset == curr.
bestLaneOffset 2144 latDist = latLaneDist;
2163 <<
" avoid overtaking on the right nv=" << nv->
getID()
2166 <<
" plannedSpeed=" <<
myVSafes.back()
2180 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
2183 }
else if (laneOffset != 0 && bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
2189 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
2194 && bestLaneOffset == 0
2197 && roundaboutEdgesAhead == 0
2203 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
2207 && bestLaneOffset == 0
2214 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
2232 if (shadow == 0 || currentShadowDist >= requiredDist) {
2235 currentShadowDist += shadow->
getLength();
2240 if (currentShadowDist < requiredDist && currentShadowDist < usableDist) {
2244 std::cout <<
" must change for shadowLane end latDist=" << latDist <<
" myLeftSpace=" <<
myLeftSpace <<
"\n";
2255 if ((ret & lcaCounter) != 0) {
2260 std::cout <<
" reqAfterInfluence=" << ret <<
" ret=" << ret <<
"\n";
2318 const bool stayInLane = laneOffset == 0 || ((state &
LCA_STRATEGIC) != 0 && (state &
LCA_STAY) != 0);
2319 const double oldLatDist = latDist;
2322 const double halfWidth =
getWidth() * 0.5;
2328 double surplusGapRight = oldCenter - halfWidth;
2331 std::cout <<
" keepLatGap laneOffset=" << laneOffset
2332 <<
" latDist=" << latDist
2335 <<
" gapFactor=" << gapFactor
2336 <<
" stayInLane=" << stayInLane <<
"\n" 2337 <<
" stayInEdge: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2340 if (surplusGapLeft < 0 || surplusGapRight < 0) {
2350 if (laneOffset != 0) {
2356 std::cout <<
" minGapLat: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n" 2364 if (stayInLane || laneOffset == 1) {
2370 if (stayInLane || laneOffset == -1) {
2377 std::cout <<
" stayInLane: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2380 if (surplusGapRight + surplusGapLeft < 0) {
2385 const double equalDeficit = 0.5 * (surplusGapLeft + surplusGapRight);
2386 if (surplusGapRight < surplusGapLeft) {
2388 const double delta =
MIN2(equalDeficit - surplusGapRight, physicalGapLeft);
2391 std::cout <<
" insufficient latSpace, move left: delta=" << delta <<
"\n";
2395 const double delta =
MIN2(equalDeficit - surplusGapLeft, physicalGapRight);
2398 std::cout <<
" insufficient latSpace, move right: delta=" << delta <<
"\n";
2403 latDist =
MAX2(
MIN2(latDist, surplusGapLeft), -surplusGapRight);
2414 std::cout <<
" wanted changeToLeft oldLatDist=" << oldLatDist <<
", blocked latGap changeToRight\n";
2416 latDist = oldLatDist;
2418 }
else if ((latDist > -
NUMERICAL_EPS * TS) && (oldLatDist < 0)) {
2420 std::cout <<
" wanted changeToRight oldLatDist=" << oldLatDist <<
", blocked latGap changeToLeft\n";
2422 latDist = oldLatDist;
2429 std::cout <<
" latDistUpdated=" << (oldLatDist - latDist) <<
"\n";
2431 blocked =
checkBlocking(neighLane, latDist, laneOffset, leaders, followers, blockers, neighLeaders, neighFollowers, neighBlockers, 0, 0,
true);
2434 state = (state & ~LCA_STAY);
2442 std::cout <<
" latDist2=" << latDist
2455 double& surplusGapRight,
double& surplusGapLeft,
2456 bool saveMinGap,
double netOverlap,
2458 std::vector<CLeaderDist>* collectBlockers) {
2463 if (others[i].first != 0 && others[i].second <= 0
2465 && (netOverlap == 0 || others[i].second + others[i].first->getVehicleType().getMinGap() < netOverlap)) {
2469 double foeRight, foeLeft;
2471 const double foeCenter = foeRight + 0.5 * res;
2472 const double gap =
MIN2(fabs(foeRight - oldCenter), fabs(foeLeft - oldCenter)) - halfWidth;
2475 const double currentMinGap = desiredMinGap * gapFactor;
2488 <<
" foe=" << foe->
getID()
2489 <<
" foeRight=" << foeRight
2490 <<
" foeLeft=" << foeLeft
2491 <<
" oldCenter=" << oldCenter
2492 <<
" gap=" << others[i].second
2493 <<
" latgap=" << gap
2494 <<
" currentMinGap=" << currentMinGap
2495 <<
" surplusGapRight=" << surplusGapRight
2496 <<
" surplusGapLeft=" << surplusGapLeft
2498 if (foeCenter < oldCenter) {
2499 surplusGapRight =
MIN2(surplusGapRight, gap - currentMinGap);
2501 surplusGapLeft =
MIN2(surplusGapLeft, gap - currentMinGap);
2504 if (foeCenter < oldCenter) {
2506 std::cout <<
" new minimum rightGap=" << gap <<
"\n";
2511 std::cout <<
" new minimum leftGap=" << gap <<
"\n";
2516 if (collectBlockers != 0) {
2518 if ((foeCenter < oldCenter && latDist < 0 && gap < (desiredMinGap - latDist))
2519 || (foeCenter > oldCenter && latDist > 0 && gap < (desiredMinGap + latDist))) {
2520 collectBlockers->push_back(others[i]);
2537 int currentDirection =
mySpeedLat >= 0 ? 1 : -1;
2538 int directionWish = latDist >= 0 ? 1 : -1;
2553 <<
" latDist=" << latDist
2555 <<
" fullLatDist=" << fullLatDist
2556 <<
" speedAccel=" << speedAccel
2557 <<
" speedDecel=" << speedDecel
2558 <<
" speedBound=" << speedBound
2561 if (speedDecel * speedAccel <= 0 && (
2563 (latDist >= 0 && speedAccel >= speedBound && speedBound >= speedDecel)
2564 || (latDist <= 0 && speedAccel <= speedBound && speedBound <= speedDecel))) {
2567 std::cout <<
" computeSpeedLat a)\n";
2574 std::cout <<
" computeSpeedLat b)\n";
2580 if ((fabs(minDistAccel) < fabs(fullLatDist)) || (fabs(minDistAccel - fullLatDist) <
NUMERICAL_EPS)) {
2582 std::cout <<
" computeSpeedLat c)\n";
2587 std::cout <<
" minDistAccel=" << minDistAccel <<
"\n";
2591 if ((fabs(minDistCurrent) < fabs(fullLatDist)) || (fabs(minDistCurrent - fullLatDist) <
NUMERICAL_EPS)) {
2593 std::cout <<
" computeSpeedLat d)\n";
2600 std::cout <<
" computeSpeedLat e)\n";
2610 const MSLane& neighLane) {
2621 myCommittedSpeed = 0;
2626 <<
" secondsToLeave=" << secondsToLeaveLane
2628 <<
" committed=" << myCommittedSpeed
2648 const double vehWidth =
getWidth();
2650 const double leftVehSide = rightVehSide + vehWidth;
2651 const double rightVehSideDest = rightVehSide + latDist;
2652 const double leftVehSideDest = leftVehSide + latDist;
2654 std::cout <<
" commitFollowSpeed" 2655 <<
" latDist=" << latDist
2656 <<
" foeOffset=" << foeOffset
2657 <<
" vehRight=" << rightVehSide
2658 <<
" vehLeft=" << leftVehSide
2659 <<
" destRight=" << rightVehSideDest
2660 <<
" destLeft=" << leftVehSideDest
2665 if (vehDist.first != 0) {
2666 const MSVehicle* leader = vehDist.first;
2668 double foeRight, foeLeft;
2671 std::cout <<
" foe=" << vehDist.first->getID()
2672 <<
" gap=" << vehDist.second
2674 <<
" foeRight=" << foeRight
2675 <<
" foeLeft=" << foeLeft
2676 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
2677 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
2680 if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
2682 assert(vehDist.second >= 0);
2685 speed =
MIN2(speed, vSafe);
2687 std::cout <<
" case1 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
2689 }
else if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)) {
2694 speed =
MIN2(speed, vSafe);
2696 std::cout <<
" case2 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
2775 const std::pair<MSVehicle*, double>& leader,
2776 const std::pair<MSVehicle*, double>& neighLead,
2777 const std::pair<MSVehicle*, double>& neighFollow,
2779 const std::vector<MSVehicle::LaneQ>& preb,
2786 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 2793 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
2808 leaders, followers, blockers,
2809 neighLeaders, neighFollowers, neighBlockers,
2811 lastBlocked, firstBlocked, latDist, blocked);
2817 result |=
getLCA(result, latDist);
2823 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
2824 << ((result &
LCA_URGENT) ?
" (urgent)" :
"")
2830 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
void * inform(void *info, MSVehicle *sender)
int getRightmostSublane() const
void updateCFRelated(const MSLeaderDistanceInfo &vehicles, double foeOffset)
find leaders/followers that are already in a car-following relationship with ego
double getMinGap() const
Get the free space in front of vehicles of this class.
static double gLateralResolution
void initDerivedParameters()
init cached parameters derived directly from model parameters
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
saves leader/follower vehicles and their distances relative to an ego vehicle
MSEdge & getEdge() const
Returns the lane's edge.
double myChangeProbThresholdLeft
double getWidth() const
Returns the lane's width.
Representation of a vehicle in the micro simulation.
void msg(const CLeaderDist &cld, double speed, int state)
send a speed recommendation to the given vehicle
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key ...
double mySpeedGainProbabilityLeft
a value for tracking the probability that a change to the left is beneficial
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
The action is due to the default of keeping right "Rechtsfahrgebot".
double myLastLateralGapRight
The action is done to help someone else.
#define RELGAIN_NORMALIZATION_MIN_SPEED
std::set< const MSVehicle * > myCFRelated
set of vehicles that are in a car-following relationship with ego (leader of followers) ...
void getSublaneBorders(int sublane, double latOffset, double &rightSide, double &leftSide) const
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const =0
Computes the vehicle's follow speed (no dawdling)
int checkBlocking(const MSLane &neighLane, double &latDist, 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 ...
#define ROUNDABOUT_DIST_BONUS
double informLeaders(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds)
bool myCanChangeFully
whether the current lane changing meneuver can be finished in a single step
bool hasInfluencer() const
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
bool debugVehicle() const
whether the current vehicles shall be debugged
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
The vehicle is blocked by left follower.
virtual std::string toString() const
print a debugging representation
At the leftmost side of the lane.
int gPrecision
the precision for floating point outputs
double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
const MSEdge * getLastEdge() const
returns the destination edge
const double SUMO_const_laneWidth
int checkStrategicChange(int ret, int laneOffset, const std::vector< MSVehicle::LaneQ > &preb, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, int currIdx, int bestLaneOffset, bool changeToBest, int lcaCounter, double currentDist, double neighDist, double laDist, int roundaboutEdgesAhead, double latLaneDist, double &latDist)
compute strategic lane change actions
The car-following model abstraction.
double mySpeedLossProbThreshold
void setOwnState(const int state)
static CLeaderDist getSlowest(const MSLeaderDistanceInfo &ldi)
get the slowest vehicle in the given info
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
void updateExpectedSublaneSpeeds(const MSLeaderInfo &ahead, int sublaneOffset, int laneIndex)
update expected speeds for each sublane of the current edge
double computeGapFactor(int state) const
compute the gap factor for the given state
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
std::vector< double > myExpectedSublaneSpeeds
expected travel speeds on all sublanes on the current edge(!)
double myTimeToImpatience
double getLength() const
Returns the lane's length.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
const MSRoute & getRoute() const
Returns the current route.
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
double getPositionOnLane() const
Get the vehicle's position along the lane.
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, int &blocked)
check whether lateral gap requirements are met override the current maneuver if necessary ...
virtual double getArrivalPos() const
Returns this vehicle's desired arrivalPos for its current route (may change on reroute) ...
void commitManoeuvre(int blocked, int blockedFully, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, const MSLane &neighLane)
commit to lane change maneuvre potentially overriding safe speed
static const double NO_NEIGHBOR
LateralAlignment getPreferredLateralAlignment() const
Get vehicle's preferred lateral alignment.
StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const
decide in which direction to move in case both directions are desirable
align with the closest sublane border
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
double length
The overall length which may be driven when using this lane without a lane change.
The action is due to the wish to be faster (tactical lc)
MSLCM_SL2015(MSVehicle &v)
used by the sublane model
#define LCA_RIGHT_IMPATIENCE
double myChangeProbThresholdRight
double getWidth() const
return the widht of this vehicle (padded for numerical stability)
bool hasStoppedVehicle() const
whether a stopped vehicle is leader
MSAbstractLaneChangeModel & getLaneChangeModel()
std::vector< double > myVSafes
speed adaptation requests by ego and surrounding vehicles
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, int &blocked)
Called to examine whether the vehicle wants to change with the given laneOffset (using the sublane mo...
#define LOOK_FORWARD_LEFT
#define MAX_ONRAMP_LENGTH
#define GAIN_PERCEPTION_THRESHOLD
#define ARRIVALPOS_LAT_THRESHOLD
Needs to stay on the current lane.
void saveBlockerLength(const MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
const std::vector< double > getSubLaneSides() const
Returns the right side offsets of this edge's sublanes.
const LaneChangeModel myModel
the type of this model
static bool overlap(double right, double left, double right2, double left2)
return whether the given intervals overlap
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
A class responsible for exchanging messages between cars involved in lane-change interaction.
const std::string & getID() const
Returns the id.
A road/street connecting two junctions.
double myLeadingBlockerLength
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...
bool cancelRequest(int state)
whether the influencer cancels the given request
double getLatDist() const
bool allowsVehicleClass(SUMOVehicleClass vclass) const
blocked in all directions
int checkBlockingVehicles(const MSVehicle *ego, const MSLeaderDistanceInfo &vehicles, double latDist, double foeOffset, bool leaders, LaneChangeAction blockType, std::vector< CLeaderDist > *collectBlockers=0) const
check whether any of the vehicles overlaps with ego
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
The action is urgent (to be defined by lc-model)
static double brakeGapEuler(const double speed, const double decel, const double headwayTime)
At the center of the lane.
static MSPModel * getModel()
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
const MSEdge * myLastEdge
expected travel speeds on all sublanes on the current edge(!)
double informLeader(int blocked, int dir, const CLeaderDist &neighLead, double remainingSeconds)
static LaneChangeAction getLCA(int state, double latDist)
compute lane change action from desired lateral distance
void informFollowers(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds, double plannedSpeed)
call informFollower for multiple followers
bool sameDirection(const StateAndDist &other) const
At the rightmost side of the lane.
#define KEEP_RIGHT_ACCEPTANCE
The action is needed to follow the route (navigational lc)
A structure representing the best lanes for continuing the current route starting at 'lane'...
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0 ...
double 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 _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
int myOwnState
The current state of the vehicle.
maintain the current alignment
int getIndex() const
Returns the lane's index.
#define LOOK_AHEAD_SPEED_MEMORY
#define LOOK_AHEAD_MIN_SPEED
bool isInternal() const
return whether this edge is an internal edge
static CLeaderDist getLongest(const MSLeaderDistanceInfo &ldi)
get the longest vehicle in the given info
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
double computeSpeedGain(double latDistSublane, double defaultNextSpeed) const
compute speedGain when moving by the given amount
#define LOOK_FORWARD_RIGHT
double myCooperativeParam
double getWidth() const
Returns the edges's width (sum over all lanes)
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
std::pair< const MSPerson *, double > PersonDist
double getMinGapLat() const
Get the minimum lateral gap that vehicles of this type maintain.
double getLength() const
Get vehicle's length [m].
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
std::pair< const MSVehicle *, double > CLeaderDist
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Influencer & getInfluencer()
Returns the velocity/lane influencer.
LaneChangeAction
The state of a vehicle's lane-change behavior.
virtual void setOwnState(const int state)
virtual void setMaxDecel(double decel)
Sets a new value for maximal comfortable deceleration [m/s^2].
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
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.
#define SPEEDGAIN_MEMORY_FACTOR
double myKeepRightProbability
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
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...
The vehicle is blocked being overlapping.
double myOrigLatDist
the complete lateral distance the vehicle wants to travel to finish its maneuver
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
std::vector< MSLane * > bestContinuations
void informFollower(int blocked, int dir, const CLeaderDist &neighFollow, double remainingSeconds, double plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
double mySpeedLat
the current lateral speed
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key ...
static double _2double(const E *const data)
converts a char-type array into the double value described by it
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 getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
No information given; use default.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
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) ...
#define SPEEDGAIN_DECAY_FACTOR
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
align with the rightmost sublane that allows keeping the current speed
virtual void prepareStep()
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
#define CUT_IN_LEFT_SPEED_THRESHOLD
The action is due to a TraCI request.
double getRightSideOnEdge() const
#define HELP_DECEL_FACTOR
double mySpeedGainProbabilityRight
a value for tracking the probability that a change to the right is beneficial
#define LATGAP_SPEED_THRESHOLD2
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
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 myCommittedSpeed
the speed when committing to a change maneuver
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane ...
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
bool myDontBrake
flag to prevent speed adaptation by slowing down
#define LATGAP_SPEED_THRESHOLD
double computeSpeedLat(double latDist)
decides the next lateral speed depending on the remaining lane change distance to be covered ...
The vehicle is blocked by right leader.
MSLane * getLane() const
Returns the lane the vehicle is on.
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, int &blocked)
helper function for doing the actual work
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right ...
public emergency vehicles
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
Called to examine whether the vehicle wants to change using the given laneOffset (this is a wrapper a...
Representation of a lane in the micro simulation.
const MSCFModel & myCarFollowModel
The vehicle's car following model.
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
int myPreviousState
lane changing state from the previous simulation step
The vehicle is blocked by right follower.
int computeSublaneShift(const MSEdge *prevEdge, const MSEdge *curEdge)
compute shift so that prevSublane + shift = newSublane
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i...
Interface for lane-change models.
int getBestLaneOffset() const
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 std::string & getID() const
Returns the name of the vehicle.
double getSpeed() const
Returns the vehicle's current speed.
#define SPEED_GAIN_MIN_SECONDS
bool amBlockingFollowerPlusNB()