37 #define MAGIC_OFFSET 1. 38 #define LOOK_FORWARD (double)10. 40 #define JAM_FACTOR (double)1. 43 #define LCA_RIGHT_IMPATIENCE (double)-1. 44 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27. 45 #define MAX_ONRAMP_LENGTH (double)200. 47 #define LOOK_AHEAD_MIN_SPEED 0.0 48 #define LOOK_AHEAD_SPEED_MEMORY 0.9 50 #define HELP_DECEL_FACTOR (double)1.0 52 #define HELP_OVERTAKE (double)(10.0 / 3.6) 53 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 55 #define KEEP_RIGHT_HEADWAY (double)2.0 57 #define URGENCY (double)2.0 59 #define ROUNDABOUT_DIST_BONUS (double)100.0 61 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 62 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 64 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 66 #define TURN_LANE_DIST (double)200.0 // the distance at which a lane leading elsewhere is considered to be a turn-lane that must be avoided 67 #define GAIN_PERCEPTION_THRESHOLD 0.05 // the minimum relative speed gain which affects the behavior 69 #define SPEED_GAIN_MIN_SECONDS 20.0 71 #define ARRIVALPOS_LAT_THRESHOLD 100.0 74 #define LATGAP_SPEED_THRESHOLD (50 / 3.6) 77 #define LATGAP_SPEED_THRESHOLD2 (50 / 3.6) 80 #define SPEEDGAIN_DECAY_FACTOR 0.5 82 #define SPEEDGAIN_MEMORY_FACTOR 0.5 108 #define DEBUG_COND (myVehicle.isSelected()) 120 mySpeedGainProbabilityRight(0),
121 mySpeedGainProbabilityLeft(0),
122 myKeepRightProbability(0),
123 myLeadingBlockerLength(0),
127 myCanChangeFully(true),
128 mySafeLatDistRight(0),
129 mySafeLatDistLeft(0),
142 myMinImpatience(myImpatience),
181 const std::vector<MSVehicle::LaneQ>& preb,
184 double& latDist,
double& maneuverDist,
int& blocked) {
187 const std::string changeType = laneOffset == -1 ?
"right" : (laneOffset == 1 ?
"left" :
"current");
189 #ifdef DEBUG_MANEUVER 198 <<
" considerChangeTo=" << changeType
205 leaders, followers, blockers,
206 neighLeaders, neighFollowers, neighBlockers,
208 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
210 result =
keepLatGap(result, leaders, followers, blockers,
211 neighLeaders, neighFollowers, neighBlockers,
212 neighLane, laneOffset, latDist, maneuverDist, blocked);
214 result |=
getLCA(result, latDist);
216 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE) 217 double latDistTmp = latDist;
220 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE) 222 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" maneuverDist=" << maneuverDist <<
" latDist=" << latDistTmp <<
" mySpeedPrev=" <<
mySpeedLat <<
" speedLat=" <<
DIST2SPEED(latDist) <<
" latDist2=" << latDist <<
"\n";
229 <<
" wantsChangeTo=" << changeType
230 <<
" latDist=" << latDist
231 <<
" maneuverDist=" << maneuverDist
239 <<
" wantsNoChangeTo=" << changeType
297 const double newSpeed =
_patchSpeed(
MAX2(min, 0.0), wanted, max, cfModel);
298 #ifdef DEBUG_PATCHSPEED 300 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
307 <<
" wanted=" << wanted
330 #ifdef DEBUG_PATCHSPEED 340 #ifdef DEBUG_PATCHSPEED 342 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
345 return MAX2(min, safe);
349 double nVSafe = wanted;
353 if (v >= min && v <= max) {
354 nVSafe =
MIN2(v, nVSafe);
356 #ifdef DEBUG_PATCHSPEED 358 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" got accel=" << (*i) <<
" nVSafe=" << nVSafe <<
"\n";
362 #ifdef DEBUG_PATCHSPEED 365 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
369 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
377 #ifdef DEBUG_PATCHSPEED 390 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 395 return (max + wanted) / (double) 2.0;
399 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 404 return (min + wanted) / (double) 2.0;
407 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 412 return (max + wanted) / (double) 2.0;
453 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 458 return (max + wanted) / (double) 2.0;
462 #if defined(DEBUG_PATCHSPEED) || defined(DEBUG_STATE) 482 if (pinfo->first >= 0) {
491 <<
" informedBy=" << sender->
getID()
492 <<
" info=" << pinfo->second
493 <<
" vSafe=" << pinfo->first
506 assert(cld.first != 0);
515 double remainingSeconds) {
521 plannedSpeed =
MIN2(plannedSpeed, v);
526 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
533 if (
gDebugFlag2) std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 537 const double dv = plannedSpeed - nv->
getSpeed();
538 const double overtakeDist = (neighLead.second
550 || dv * remainingSeconds < overtakeDist) {
565 <<
" cannot overtake leader nv=" << nv->
getID()
567 <<
" remainingSeconds=" << remainingSeconds
568 <<
" targetSpeed=" << targetSpeed
569 <<
" nextSpeed=" << nextSpeed
580 <<
" cannot overtake fast leader nv=" << nv->
getID()
582 <<
" remainingSeconds=" << remainingSeconds
583 <<
" targetSpeed=" << targetSpeed
594 <<
" wants to overtake leader nv=" << nv->
getID()
596 <<
" remainingSeconds=" << remainingSeconds
597 <<
" currentGap=" << neighLead.second
599 <<
" overtakeDist=" << overtakeDist
609 }
else if (neighLead.first != 0) {
612 double dv, nextNVSpeed;
632 std::cout <<
" not blocked by leader nv=" << nv->
getID()
634 <<
" gap=" << neighLead.second
635 <<
" nextGap=" << neighLead.second - dv
637 <<
" targetSpeed=" << targetSpeed
641 return MIN2(targetSpeed, plannedSpeed);
653 double remainingSeconds,
654 double plannedSpeed) {
658 if (
gDebugFlag2) std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 665 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
668 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
687 const double neighNewSpeed1s =
MAX2(0., nv->
getSpeed() - helpDecel);
688 const double dv = plannedSpeed - neighNewSpeed1s;
690 const double decelGap = neighFollow.second + dv;
696 <<
" egoNV=" << plannedSpeed
697 <<
" nvNewSpeed=" << neighNewSpeed
698 <<
" nvNewSpeed1s=" << neighNewSpeed1s
699 <<
" deltaGap=" << dv
700 <<
" decelGap=" << decelGap
701 <<
" secGap=" << secureGap
705 if (decelGap > 0 && decelGap >= secureGap) {
720 std::cout <<
" wants to cut in before nv=" << nv->
getID()
721 <<
" vsafe1=" << vsafe1
722 <<
" vsafe=" << vsafe
727 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap +
POSITION_EPS)) {
732 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
740 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
756 std::cout <<
" wants right follower to slow down a bit\n";
762 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
771 const double overtakeDist = (neighFollow.second
777 const double needDV = overtakeDist / remainingSeconds;
785 <<
" wants to be overtaken by=" << nv->
getID()
786 <<
" overtakeDist=" << overtakeDist
788 <<
" vhelp=" << vhelp
789 <<
" needDV=" << needDV
795 }
else if (neighFollow.first != 0) {
805 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
813 const std::vector<CLeaderDist>& blockers,
814 double remainingSeconds) {
821 plannedSpeed =
MIN2(plannedSpeed, safe);
824 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
825 plannedSpeed =
MIN2(plannedSpeed,
informLeader(blocked, dir, *it, remainingSeconds));
833 const std::vector<CLeaderDist>& blockers,
834 double remainingSeconds,
835 double plannedSpeed) {
837 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
838 informFollower(blocked, dir, *it, remainingSeconds, plannedSpeed);
866 const double halfWidth =
getWidth() * 0.5;
876 std::vector<double> newExpectedSpeeds;
885 const std::vector<MSLane*>& lanes = currEdge->
getLanes();
886 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
888 for (
int i = 0; i < subLanes; ++i) {
889 newExpectedSpeeds.push_back((*it_lane)->getVehicleMaxSpeed(&
myVehicle));
897 if (subLaneShift < std::numeric_limits<int>::max()) {
899 const int newI = i + subLaneShift;
900 if (newI > 0 && newI < (
int)newExpectedSpeeds.size()) {
918 const std::vector<MSLane*>& lanes = prevEdge->
getLanes();
919 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
920 const MSLane* lane = *it_lane;
921 for (MSLinkCont::const_iterator it_link = lane->
getLinkCont().begin(); it_link != lane->
getLinkCont().end(); ++it_link) {
922 if (&((*it_link)->getLane()->getEdge()) == curEdge) {
924 const MSLane* target = (*it_link)->getLane();
925 const std::vector<MSLane*>& lanes2 = curEdge->
getLanes();
926 for (std::vector<MSLane*>::const_iterator it_lane2 = lanes2.begin(); it_lane2 != lanes2.end(); ++it_lane2) {
927 const MSLane* lane2 = *it_lane2;
928 if (lane2 == target) {
929 return prevShift + curShift;
940 return std::numeric_limits<int>::max();
970 #if defined(DEBUG_MANEUVER) || defined(DEBUG_STATE) 989 const std::vector<MSVehicle::LaneQ>& preb,
992 double& latDist,
double& maneuverDist,
int& blocked) {
997 int bestLaneOffset = 0;
998 double currentDist = 0;
999 double neighDist = 0;
1006 for (
int p = 0; p < (int) preb.size(); ++p) {
1007 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1008 assert(p + laneOffset < (
int)preb.size());
1010 neigh = preb[p + laneOffset];
1011 currentDist = curr.
length;
1012 neighDist = neigh.
length;
1013 bestLaneOffset = curr.bestLaneOffset;
1015 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
1016 #ifdef DEBUG_WANTSCHANGE 1020 <<
" bestLaneOffsetOld=" << bestLaneOffset
1021 <<
" bestLaneOffsetNew=" << laneOffset
1025 bestLaneOffset = laneOffset;
1031 double driveToNextStop = -std::numeric_limits<double>::max();
1040 #ifdef DEBUG_WANTS_CHANGE 1045 <<
" stopPos=" << stopPos
1046 <<
" currentDist=" << currentDist
1047 <<
" neighDist=" << neighDist
1051 currentDist =
MAX2(currentDist, stopPos);
1052 neighDist =
MAX2(neighDist, stopPos);
1055 const bool right = (laneOffset == -1);
1056 const bool left = (laneOffset == 1);
1059 const bool changeToBest = (right && bestLaneOffset < 0) || (left && bestLaneOffset > 0) || (laneOffset == 0 && bestLaneOffset == 0);
1085 #ifdef DEBUG_WANTSCHANGE 1092 <<
"\n leaders=" << leaders.
toString()
1093 <<
"\n followers=" << followers.
toString()
1094 <<
"\n blockers=" << blockers.
toString()
1095 <<
"\n neighLeaders=" << neighLeaders.
toString()
1096 <<
"\n neighFollowers=" << neighFollowers.
toString()
1097 <<
"\n neighBlockers=" << neighBlockers.
toString()
1098 <<
"\n changeToBest=" << changeToBest
1099 <<
" latLaneDist=" << latLaneDist
1107 if (lastBlocked != firstBlocked) {
1167 int roundaboutEdgesAhead = 0;
1169 if ((*it) !=
nullptr && (*it)->getEdge().isRoundabout()) {
1170 roundaboutEdgesAhead += 1;
1171 }
else if (roundaboutEdgesAhead > 0) {
1176 int roundaboutEdgesAheadNeigh = 0;
1178 if ((*it) !=
nullptr && (*it)->getEdge().isRoundabout()) {
1179 roundaboutEdgesAheadNeigh += 1;
1180 }
else if (roundaboutEdgesAheadNeigh > 0) {
1185 if (roundaboutEdgesAhead > 1) {
1189 if (roundaboutEdgesAhead > 0) {
1190 #ifdef DEBUG_ROUNDABOUTS 1192 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1197 if (laneOffset != 0) {
1209 roundaboutEdgesAhead,
1214 if ((ret &
LCA_STAY) != 0 && latDist == 0) {
1224 if (changeToBest && abs(bestLaneOffset) > 1
1229 #ifdef DEBUG_WANTSCHANGE 1231 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1240 if (*firstBlocked != neighLeadLongest) {
1243 std::vector<CLeaderDist> collectLeadBlockers;
1244 std::vector<CLeaderDist> collectFollowBlockers;
1245 int blockedFully = 0;
1248 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1249 leaders, followers, blockers,
1250 neighLeaders, neighFollowers, neighBlockers, &collectLeadBlockers, &collectFollowBlockers,
1251 false, gapFactor, &blockedFully);
1253 const double absLaneOffset = fabs(bestLaneOffset != 0 ? bestLaneOffset : latDist /
SUMO_const_laneWidth);
1254 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1257 const double plannedSpeed =
informLeaders(blocked, myLca, collectLeadBlockers, remainingSeconds);
1259 if (plannedSpeed >= 0) {
1261 informFollowers(blocked, myLca, collectFollowBlockers, remainingSeconds, plannedSpeed);
1263 if (plannedSpeed > 0) {
1264 commitManoeuvre(blocked, blockedFully, leaders, neighLeaders, neighLane, maneuverDist);
1266 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) 1273 <<
" remainingSeconds=" << remainingSeconds
1274 <<
" plannedSpeed=" << plannedSpeed
1284 if (roundaboutEdgesAhead > 1) {
1293 if ((ret & LCA_STAY) == 0) {
1294 latDist = latLaneDist;
1295 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1296 leaders, followers, blockers,
1297 neighLeaders, neighFollowers, neighBlockers);
1312 const double inconvenience = (latLaneDist < 0
1326 && (changeToBest ||
currentDistAllows(neighDist, abs(bestLaneOffset) + 1, laDist))) {
1329 #ifdef DEBUG_COOPERATE 1336 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1346 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1347 leaders, followers, blockers,
1348 neighLeaders, neighFollowers, neighBlockers);
1372 const double vehWidth =
getWidth();
1374 const double leftVehSide = rightVehSide + vehWidth;
1376 double defaultNextSpeed = std::numeric_limits<double>::max();
1378 int leftmostOnEdge = (int)sublaneSides.size() - 1;
1379 while (leftmostOnEdge > 0 && sublaneSides[leftmostOnEdge] > leftVehSide) {
1382 int rightmostOnEdge = leftmostOnEdge;
1383 while (rightmostOnEdge > 0 && sublaneSides[rightmostOnEdge] > rightVehSide +
NUMERICAL_EPS) {
1385 #ifdef DEBUG_WANTSCHANGE 1387 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1388 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1394 #ifdef DEBUG_WANTSCHANGE 1396 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1397 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1400 double maxGain = -std::numeric_limits<double>::max();
1401 double maxGainRight = -std::numeric_limits<double>::max();
1402 double maxGainLeft = -std::numeric_limits<double>::max();
1403 double latDistNice = std::numeric_limits<double>::max();
1406 const double leftMax =
MAX2(
1409 assert(leftMax <= edge.
getWidth());
1410 int sublaneCompact =
MAX2(iMin, rightmostOnEdge - 1);
1412 #ifdef DEBUG_WANTSCHANGE 1414 <<
" checking sublanes rightmostOnEdge=" << rightmostOnEdge
1415 <<
" leftmostOnEdge=" << leftmostOnEdge
1417 <<
" leftMax=" << leftMax
1418 <<
" sublaneCompact=" << sublaneCompact
1421 for (
int i = iMin; i < (int)sublaneSides.size(); ++i) {
1422 if (sublaneSides[i] + vehWidth < leftMax) {
1428 while (vMin > 0 && j < (
int)sublaneSides.size() && sublaneSides[j] < sublaneSides[i] + vehWidth) {
1434 const double currentLatDist = sublaneSides[i] - rightVehSide;
1436 if (relativeGain > maxGain) {
1437 maxGain = relativeGain;
1440 latDist = currentLatDist;
1441 #ifdef DEBUG_WANTSCHANGE 1443 std::cout <<
" i=" << i <<
" newLatDist=" << latDist <<
" relGain=" << relativeGain <<
"\n";
1449 if (currentLatDist > 0
1454 latDist = currentLatDist;
1457 #ifdef DEBUG_WANTSCHANGE 1459 std::cout <<
" i=" << i <<
" rightmostOnEdge=" << rightmostOnEdge <<
" vMin=" << vMin <<
" relGain=" << relativeGain <<
" sublaneCompact=" << sublaneCompact <<
" curLatDist=" << currentLatDist <<
"\n";
1463 maxGainRight =
MAX2(maxGainRight, relativeGain);
1465 maxGainLeft =
MAX2(maxGainLeft, relativeGain);
1467 const double subAlignDist = sublaneSides[i] - rightVehSide;
1468 if (fabs(subAlignDist) < fabs(latDistNice)) {
1469 latDistNice = subAlignDist;
1470 #ifdef DEBUG_WANTSCHANGE 1472 <<
" nicest sublane=" << i
1473 <<
" side=" << sublaneSides[i]
1474 <<
" rightSide=" << rightVehSide
1475 <<
" latDistNice=" << latDistNice
1476 <<
" maxGainR=" << maxGainRight
1477 <<
" maxGainL=" << maxGainLeft
1484 if (maxGainRight != -std::numeric_limits<double>::max()) {
1485 #ifdef DEBUG_WANTSCHANGE 1491 #ifdef DEBUG_WANTSCHANGE 1497 if (maxGainLeft != -std::numeric_limits<double>::max()) {
1498 #ifdef DEBUG_WANTSCHANGE 1504 #ifdef DEBUG_WANTSCHANGE 1511 if ((fabs(maxGainRight) <
NUMERICAL_EPS || maxGainRight == -std::numeric_limits<double>::max())
1512 && (right || (alternatives &
LCA_RIGHT) == 0)) {
1515 if ((fabs(maxGainLeft) <
NUMERICAL_EPS || maxGainLeft == -std::numeric_limits<double>::max())
1516 && (left || (alternatives &
LCA_LEFT) == 0)) {
1521 #ifdef DEBUG_WANTSCHANGE 1524 <<
" defaultNextSpeed=" << defaultNextSpeed
1525 <<
" maxGain=" << maxGain
1526 <<
" maxGainRight=" << maxGainRight
1527 <<
" maxGainLeft=" << maxGainLeft
1528 <<
" latDist=" << latDist
1529 <<
" latDistNice=" << latDistNice
1530 <<
" sublaneCompact=" << sublaneCompact
1536 if (right && maxGainRight >= 0) {
1543 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1545 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1546 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1548 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1549 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1554 #ifdef DEBUG_WANTSCHANGE 1557 <<
" considering keepRight:" 1559 <<
" neighDist=" << neighDist
1561 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1563 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1564 <<
" acceptanceTime=" << acceptanceTime
1565 <<
" fullSpeedGap=" << fullSpeedGap
1566 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1567 <<
" dProb=" << deltaProb
1578 latDist = latLaneDist;
1579 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1580 leaders, followers, blockers,
1581 neighLeaders, neighFollowers, neighBlockers);
1587 #ifdef DEBUG_WANTSCHANGE 1592 <<
" neighDist=" << neighDist
1595 <<
" latDist=" << latDist
1604 int blockedFully = 0;
1605 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1606 leaders, followers, blockers,
1607 neighLeaders, neighFollowers, neighBlockers,
1608 nullptr,
nullptr,
false, 0, &blockedFully);
1617 #ifdef DEBUG_WANTSCHANGE 1622 <<
" latDist=" << latDist
1623 <<
" neighDist=" << neighDist
1626 <<
" stayInLane=" << stayInLane
1637 int blockedFully = 0;
1638 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1639 leaders, followers, blockers,
1640 neighLeaders, neighFollowers, neighBlockers,
1641 nullptr,
nullptr,
false, 0, &blockedFully);
1650 double latDistSublane = 0.;
1652 const double halfVehWidth =
getWidth() * 0.5;
1655 && bestLaneOffset == 0
1675 #ifdef DEBUG_WANTSCHANGE 1689 switch (turnInfo.second) {
1718 latDistSublane = latDistNice;
1721 latDistSublane = sublaneSides[sublaneCompact] - rightVehSide;
1729 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) || defined(DEBUG_MANEUVER) 1734 <<
" latDist=" << latDist
1735 <<
" latDistSublane=" << latDistSublane
1736 <<
" relGainSublane=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed)
1737 <<
" maneuverDist=" << maneuverDist
1747 #if defined(DEBUG_WANTSCHANGE) 1749 <<
" speedGain=" <<
computeSpeedGain(latDistSublane, defaultNextSpeed) <<
")\n";
1756 && ((myManeuverDist < 0 && latDistSublane > 0) || (
myManeuverDist > 0 && latDistSublane < 0))) {
1757 #if defined(DEBUG_WANTSCHANGE) 1759 std::cout <<
" aborting sublane change due to prior maneuver\n";
1764 latDist = latDistSublane;
1769 #ifdef DEBUG_WANTSCHANGE 1772 <<
" latDist=" << latDist
1780 #ifdef DEBUG_WANTSCHANGE 1786 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset,
1787 leaders, followers, blockers,
1788 neighLeaders, neighFollowers, neighBlockers);
1815 #ifdef DEBUG_WANTSCHANGE 1832 if ((*blocked) !=
nullptr) {
1834 #ifdef DEBUG_SLOWDOWN 1858 (*blocked)->getCarFollowModel().getMaxDecel()));
1869 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1885 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1897 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1903 <<
" potential=" << potential
1919 <<
"vSafe=" << vSafe <<
" -> accel=" << accel <<
"\n";
1929 const MSLane* lane = lanes[laneIndex];
1931 assert(preb.size() == lanes.size());
1933 for (
int sublane = 0; sublane < (int)ahead.
numSublanes(); ++sublane) {
1934 const int edgeSublane = sublane + sublaneOffset;
1942 const MSVehicle* leader = ahead[sublane].first;
1943 const double gap = ahead[sublane].second;
1945 if (leader ==
nullptr) {
1954 #ifdef DEBUG_EXPECTED_SLSPEED 1956 std::cout <<
SIMTIME <<
" veh=" <<
myVehicle.
getID() <<
" updateExpectedSublaneSpeeds edgeSublane=" << edgeSublane <<
" leader=" << leader->
getID() <<
" gap=" << gap <<
" vSafe=" << vSafe <<
"\n";
1959 const double deltaV = vMax - leader->
getSpeed();
1960 if (deltaV > 0 && gap / deltaV < 5) {
1963 const double foreCastTime = 10;
1964 const double gapClosingTime = gap / deltaV;
1965 vSafe = (gapClosingTime * vSafe + (foreCastTime - gapClosingTime) * leader->
getSpeed()) / foreCastTime;
1972 double foeRight, foeLeft;
1976 if (leader.first != 0) {
1979 vSafe =
MIN2(vSafe, vSafePed);
1982 vSafe =
MIN2(vMax, vSafe);
1984 myExpectedSublaneSpeeds[edgeSublane] = memoryFactor * myExpectedSublaneSpeeds[edgeSublane] + (1 - memoryFactor) * vSafe;
1996 double result = std::numeric_limits<double>::max();
1999 const double vehWidth =
getWidth();
2001 const double leftVehSide = rightVehSide + vehWidth;
2002 for (
int i = 0; i < (int)sublaneSides.size(); ++i) {
2003 if (
overlap(rightVehSide, leftVehSide, sublaneSides[i], sublaneSides[i] + res)) {
2009 return result - defaultNextSpeed;
2016 double maxLength = -1;
2018 if (ldi[i].first != 0) {
2019 const double length = ldi[i].first->getVehicleType().getLength();
2020 if (length > maxLength) {
2033 double minSpeed = std::numeric_limits<double>::max();
2035 if (ldi[i].first != 0) {
2036 const double speed = ldi[i].first->getSpeed();
2037 if (speed < minSpeed) {
2055 std::vector<CLeaderDist>* collectLeadBlockers,
2056 std::vector<CLeaderDist>* collectFollowBlockers,
2057 bool keepLatGapManeuver,
2059 int* retBlockedFully) {
2061 if (!keepLatGapManeuver) {
2063 maneuverDist = latDist;
2066 latDist =
MAX2(
MIN2(latDist, maxDist), -maxDist);
2074 if (laneOffset != 0) {
2085 if (laneOffset != 0) {
2089 #ifdef DEBUG_BLOCKING 2091 std::cout <<
" checkBlocking latDist=" << latDist <<
" mySafeLatDistRight=" << mySafeLatDistRight <<
" mySafeLatDistLeft=" << mySafeLatDistLeft <<
"\n";
2101 }
else if (!forcedTraCIChange) {
2102 latDist =
MAX2(latDist, -mySafeLatDistRight);
2107 }
else if (!forcedTraCIChange) {
2108 latDist =
MIN2(latDist, mySafeLatDistLeft);
2113 #ifdef DEBUG_BLOCKING 2129 if (laneOffset != 0) {
2132 mySafeLatDistRight, mySafeLatDistLeft, collectLeadBlockers);
2135 mySafeLatDistRight, mySafeLatDistLeft, collectFollowBlockers);
2138 int blockedFully = 0;
2143 if (laneOffset != 0) {
2146 mySafeLatDistRight, mySafeLatDistLeft, collectLeadBlockers);
2149 mySafeLatDistRight, mySafeLatDistLeft, collectFollowBlockers);
2151 if (retBlockedFully !=
nullptr) {
2152 *retBlockedFully = blockedFully;
2159 blocked |= blockedFully;
2164 if (collectFollowBlockers !=
nullptr && collectLeadBlockers !=
nullptr) {
2166 for (std::vector<CLeaderDist>::const_iterator it2 = collectLeadBlockers->begin(); it2 != collectLeadBlockers->end(); ++it2) {
2167 for (std::vector<CLeaderDist>::iterator it = collectFollowBlockers->begin(); it != collectFollowBlockers->end();) {
2168 if ((*it2).first == (*it).first) {
2169 #ifdef DEBUG_BLOCKING 2171 std::cout <<
" removed follower " << (*it).first->getID() <<
" because it is already a leader\n";
2174 it = collectFollowBlockers->erase(it);
2188 double latDist,
double foeOffset,
bool leaders,
LaneChangeAction blockType,
2189 double& safeLatGapRight,
double& safeLatGapLeft,
2190 std::vector<CLeaderDist>* collectBlockers)
const {
2192 const double vehWidth =
getWidth();
2194 const double leftVehSide = rightVehSide + vehWidth;
2195 const double rightVehSideDest = rightVehSide + latDist;
2196 const double leftVehSideDest = leftVehSide + latDist;
2197 const double rightNoOverlap =
MIN2(rightVehSideDest, rightVehSide);
2198 const double leftNoOverlap =
MAX2(leftVehSideDest, leftVehSide);
2199 #ifdef DEBUG_BLOCKING 2201 std::cout <<
" checkBlockingVehicles" 2202 <<
" latDist=" << latDist
2203 <<
" foeOffset=" << foeOffset
2204 <<
" vehRight=" << rightVehSide
2205 <<
" vehLeft=" << leftVehSide
2206 <<
" rightNoOverlap=" << rightNoOverlap
2207 <<
" leftNoOverlap=" << leftNoOverlap
2208 <<
" destRight=" << rightVehSideDest
2209 <<
" destLeft=" << leftVehSideDest
2210 <<
" leaders=" << leaders
2216 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2218 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2219 const MSVehicle* leader = vehDist.first;
2222 std::swap(leader, follower);
2225 double foeRight, foeLeft;
2227 const bool overlapBefore =
overlap(rightVehSide, leftVehSide, foeRight, foeLeft);
2228 const bool overlapDest =
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft);
2229 const bool overlapAny =
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft);
2230 #ifdef DEBUG_BLOCKING 2232 std::cout <<
" foe=" << vehDist.first->getID()
2233 <<
" gap=" << vehDist.second
2235 <<
" foeRight=" << foeRight
2236 <<
" foeLeft=" << foeLeft
2237 <<
" overlapBefore=" << overlapBefore
2238 <<
" overlap=" << overlapAny
2239 <<
" overlapDest=" << overlapDest
2244 if (vehDist.second < 0) {
2245 if (overlapBefore && !overlapDest) {
2246 #ifdef DEBUG_BLOCKING 2248 std::cout <<
" ignoring current overlap to come clear\n";
2252 #ifdef DEBUG_BLOCKING 2258 if (collectBlockers ==
nullptr) {
2261 collectBlockers->push_back(vehDist);
2277 const double expectedGap =
MSCFModel::gapExtrapolation(timeTillAction, vehDist.second, leader->
getSpeed(), follower->
getSpeed(), leaderAccel, followerAccel, std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
2280 const double followerExpectedSpeed = follower->
getSpeed() + timeTillAction * followerAccel;
2281 const double leaderExpectedSpeed =
MAX2(0., leader->
getSpeed() + timeTillAction * leaderAccel);
2284 #if defined(DEBUG_ACTIONSTEPS) && defined(DEBUG_BLOCKING) 2286 std::cout <<
" timeTillAction=" << timeTillAction
2287 <<
" followerAccel=" << followerAccel
2288 <<
" followerExpectedSpeed=" << followerExpectedSpeed
2289 <<
" leaderAccel=" << leaderAccel
2290 <<
" leaderExpectedSpeed=" << leaderExpectedSpeed
2291 <<
"\n gap=" << vehDist.second
2292 <<
" gapChange=" << (expectedGap - vehDist.second)
2293 <<
" expectedGap=" << expectedGap
2294 <<
" expectedSecureGap=" << expectedSecureGap
2295 <<
" safeLatGapLeft=" << safeLatGapLeft
2296 <<
" safeLatGapRight=" << safeLatGapRight
2303 if (expectedGap < secureGap2) {
2305 if (foeRight > leftVehSide) {
2306 safeLatGapLeft =
MIN2(safeLatGapLeft, foeRight - leftVehSide);
2307 }
else if (foeLeft < rightVehSide) {
2308 safeLatGapRight =
MIN2(safeLatGapRight, rightVehSide - foeLeft);
2311 #ifdef DEBUG_BLOCKING 2313 std::cout <<
" blocked by " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2314 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor()
2315 <<
" safeLatGapLeft=" << safeLatGapLeft <<
" safeLatGapRight=" << safeLatGapRight
2319 result |= blockType;
2320 if (collectBlockers ==
nullptr) {
2323 collectBlockers->push_back(vehDist);
2325 #ifdef DEBUG_BLOCKING 2326 }
else if (
gDebugFlag2 && expectedGap < expectedSecureGap) {
2327 std::cout <<
" ignore blocker " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" expectedGap=" << expectedGap
2328 <<
" expectedSecureGap=" << expectedSecureGap <<
" secGap2=" << secureGap2 <<
" safetyFactor=" <<
getSafetyFactor() <<
"\n";
2346 const double leftVehSide = rightVehSide + vehWidth;
2347 #ifdef DEBUG_BLOCKING 2349 std::cout <<
" updateCFRelated foeOffset=" << foeOffset <<
" vehicles=" << vehicles.
toString() <<
"\n";
2352 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
2354 if (vehDist.first != 0 &&
myCFRelated.count(vehDist.first) == 0) {
2355 double foeRight, foeLeft;
2357 if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft) && (vehDist.second >= 0
2363 && -vehDist.second < vehDist.first->getVehicleType().getMinGap()
2366 #ifdef DEBUG_BLOCKING 2368 std::cout <<
" ignoring cfrelated foe=" << vehDist.first->getID() <<
" gap=" << vehDist.second
2370 <<
" foeOffset=" << foeOffset
2371 <<
" egoR=" << rightVehSide <<
" egoL=" << leftVehSide
2372 <<
" iR=" << foeRight <<
" iL=" << foeLeft
2387 assert(right <= left);
2388 assert(right2 <= left2);
2410 return changeReason;
2417 if (sd1.
state == 0) {
2419 }
else if (sd2.
state == 0) {
2429 #ifdef DEBUG_WANTSCHANGE 2435 <<
" dir1=" << sd1.
dir 2439 <<
" dir2=" << sd2.
dir 2440 <<
" reason1=" << reason1
2441 <<
" reason2=" << reason2
2447 if (reason1 < reason2) {
2449 return (!can1 && can2 && sd1.
sameDirection(sd2)) ? sd2 : sd1;
2451 }
else if (reason1 > reason2) {
2453 return (!can2 && can1 && sd1.
sameDirection(sd2)) ? sd1 : sd2;
2461 }
else if (sd2.
dir == 0) {
2466 assert(sd1.
dir == -1);
2467 assert(sd2.
dir == 1);
2470 }
else if (sd2.
latDist >= 0) {
2478 return can1 ? sd1 : sd2;
2501 const std::vector<MSVehicle::LaneQ>& preb,
2510 int roundaboutEdgesAhead,
2514 const bool right = (laneOffset == -1);
2515 const bool left = (laneOffset == 1);
2527 #ifdef DEBUG_STRATEGIC_CHANGE 2532 <<
" laDist=" << laDist
2533 <<
" currentDist=" << currentDist
2534 <<
" usableDist=" << usableDist
2535 <<
" bestLaneOffset=" << bestLaneOffset
2536 <<
" best.length=" << best.
length 2537 <<
" maxJam=" << maxJam
2538 <<
" neighLeftPlace=" << neighLeftPlace
2544 if (laneOffset != 0 && changeToBest && bestLaneOffset == curr.
bestLaneOffset 2547 latDist = latLaneDist;
2564 #ifdef DEBUG_STRATEGIC_CHANGE 2567 <<
" avoid overtaking on the right nv=" << nv->
getID()
2577 if (!changeToBest && (
currentDistDisallows(neighLeftPlace, abs(bestLaneOffset) + 2, laDist))) {
2584 #ifdef DEBUG_STRATEGIC_CHANGE 2586 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
2592 && bestLaneOffset == 0
2595 && roundaboutEdgesAhead == 0
2600 #ifdef DEBUG_STRATEGIC_CHANGE 2602 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
2607 && bestLaneOffset == 0
2613 #ifdef DEBUG_STRATEGIC_CHANGE 2615 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
2629 MSLane* shadowPrev =
nullptr;
2631 if (*it ==
nullptr) {
2635 if (shadow ==
nullptr || currentShadowDist >= requiredDist) {
2638 if (shadowPrev !=
nullptr) {
2641 currentShadowDist += shadow->
getLength();
2642 shadowPrev = shadow;
2643 #ifdef DEBUG_STRATEGIC_CHANGE 2645 std::cout <<
" shadow=" << shadow->
getID() <<
" currentShadowDist=" << currentShadowDist <<
"\n";
2649 #ifdef DEBUG_STRATEGIC_CHANGE 2654 if (currentShadowDist < requiredDist && currentShadowDist < usableDist) {
2657 #ifdef DEBUG_STRATEGIC_CHANGE 2659 std::cout <<
" must change for shadowLane end latDist=" << latDist <<
" myLeftSpace=" <<
myLeftSpace <<
"\n";
2667 #if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI) 2679 }
else if (((retTraCI &
LCA_RIGHT) != 0 && laneOffset < 0)
2680 || ((retTraCI &
LCA_LEFT) != 0 && laneOffset > 0)) {
2682 latDist = latLaneDist;
2685 #if defined(DEBUG_STRATEGIC_CHANGE) || defined(DEBUG_TRACI) 2687 std::cout <<
" reqAfterInfluence=" << ret <<
" ret=" << ret <<
"\n";
2711 double& maneuverDist,
2747 const bool stayInLane = laneOffset == 0 || ((state &
LCA_STRATEGIC) != 0 && (state &
LCA_STAY) != 0);
2748 const double oldLatDist = latDist;
2751 const double halfWidth =
getWidth() * 0.5;
2757 double surplusGapRight = oldCenter - halfWidth;
2759 #ifdef DEBUG_KEEP_LATGAP 2761 std::cout <<
"\n " <<
SIMTIME <<
" keepLatGap() laneOffset=" << laneOffset
2762 <<
" latDist=" << latDist
2765 <<
" gapFactor=" << gapFactor
2766 <<
" stayInLane=" << stayInLane <<
"\n" 2767 <<
" stayInEdge: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2771 if (surplusGapLeft < 0 || surplusGapRight < 0) {
2781 if (laneOffset != 0) {
2786 #ifdef DEBUG_KEEP_LATGAP 2788 std::cout <<
" minGapLat: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n" 2797 if (stayInLane || laneOffset == 1) {
2803 if (stayInLane || laneOffset == -1) {
2809 #ifdef DEBUG_KEEP_LATGAP 2811 std::cout <<
" stayInLane: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2815 if (surplusGapRight + surplusGapLeft < 0) {
2820 const double equalDeficit = 0.5 * (surplusGapLeft + surplusGapRight);
2821 if (surplusGapRight < surplusGapLeft) {
2823 const double delta =
MIN2(equalDeficit - surplusGapRight, physicalGapLeft);
2825 maneuverDist = delta;
2826 #ifdef DEBUG_KEEP_LATGAP 2828 std::cout <<
" insufficient latSpace, move left: delta=" << delta <<
"\n";
2833 const double delta =
MIN2(equalDeficit - surplusGapLeft, physicalGapRight);
2835 maneuverDist = -delta;
2836 #ifdef DEBUG_KEEP_LATGAP 2838 std::cout <<
" insufficient latSpace, move right: delta=" << delta <<
"\n";
2844 latDist =
MAX2(
MIN2(latDist, surplusGapLeft), -surplusGapRight);
2845 maneuverDist =
MAX2(
MIN2(maneuverDist, surplusGapLeft), -surplusGapRight);
2846 #ifdef DEBUG_KEEP_LATGAP 2848 std::cout <<
" adapted latDist=" << latDist <<
" maneuverDist=" << maneuverDist <<
" (old=" << oldLatDist <<
")\n";
2858 #ifdef DEBUG_KEEP_LATGAP 2860 std::cout <<
" traci influenced latDist=" << latDist <<
"\n";
2866 const bool traciChange = (state &
LCA_TRACI) != 0;
2867 if (nonSublaneChange && !traciChange) {
2869 #ifdef DEBUG_KEEP_LATGAP 2871 std::cout <<
" wanted changeToLeft oldLatDist=" << oldLatDist <<
", blocked latGap changeToRight\n";
2874 latDist = oldLatDist;
2877 #ifdef DEBUG_KEEP_LATGAP 2879 std::cout <<
" wanted changeToRight oldLatDist=" << oldLatDist <<
", blocked latGap changeToLeft\n";
2882 latDist = oldLatDist;
2892 #ifdef DEBUG_KEEP_LATGAP 2894 std::cout <<
" latDistUpdated=" << latDist <<
" oldLatDist=" << oldLatDist <<
"\n";
2897 blocked =
checkBlocking(neighLane, latDist, maneuverDist, laneOffset, leaders, followers, blockers, neighLeaders, neighFollowers, neighBlockers,
nullptr,
nullptr, nonSublaneChange);
2900 state = (state & ~LCA_STAY);
2911 #if defined(DEBUG_KEEP_LATGAP) || defined(DEBUG_STATE) 2913 std::cout <<
" latDist2=" << latDist
2927 double& surplusGapRight,
double& surplusGapLeft,
2928 bool saveMinGap,
double netOverlap,
2930 std::vector<CLeaderDist>* collectBlockers) {
2935 if (others[i].first != 0 && others[i].second <= 0
2937 && (netOverlap == 0 || others[i].second + others[i].first->getVehicleType().getMinGap() < netOverlap)) {
2941 double foeRight, foeLeft;
2943 const double foeCenter = foeRight + 0.5 * res;
2944 const double gap =
MIN2(fabs(foeRight - oldCenter), fabs(foeLeft - oldCenter)) - halfWidth;
2947 const double currentMinGap = desiredMinGap * gapFactor;
2958 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP) 2960 std::cout <<
" updateGaps" 2962 <<
" foe=" << foe->
getID()
2963 <<
" foeRight=" << foeRight
2964 <<
" foeLeft=" << foeLeft
2965 <<
" oldCenter=" << oldCenter
2966 <<
" gap=" << others[i].second
2967 <<
" latgap=" << gap
2968 <<
" currentMinGap=" << currentMinGap
2969 <<
" surplusGapRight=" << surplusGapRight
2970 <<
" surplusGapLeft=" << surplusGapLeft
2978 if (foeCenter < oldCenter) {
2980 surplusGapRight =
MIN3(surplusGapRight, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
2983 surplusGapLeft =
MIN3(surplusGapLeft, gap - currentMinGap,
MAX2(currentMinGap, gap - foeManeuverDist));
2986 if (foeCenter < oldCenter) {
2987 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP) 2989 std::cout <<
" new minimum rightGap=" << gap <<
"\n";
2994 #if defined(DEBUG_BLOCKING) || defined(DEBUG_KEEP_LATGAP) 2996 std::cout <<
" new minimum leftGap=" << gap <<
"\n";
3002 if (collectBlockers !=
nullptr) {
3004 if ((foeCenter < oldCenter && latDist < 0 && gap < (desiredMinGap - latDist))
3005 || (foeCenter > oldCenter && latDist > 0 && gap < (desiredMinGap + latDist))) {
3006 collectBlockers->push_back(others[i]);
3023 int currentDirection =
mySpeedLat >= 0 ? 1 : -1;
3024 int directionWish = latDist >= 0 ? 1 : -1;
3028 #ifdef DEBUG_MANEUVER 3032 <<
" computeSpeedLat()" 3033 <<
" currentDirection=" << currentDirection
3034 <<
" directionWish=" << directionWish
3040 if (directionWish == 1) {
3051 double speedAccelSafe = latDist * speedAccel >= 0 ? speedAccel : 0;
3059 if (maneuverDist * latDist > 0) {
3060 maneuverDist = fullLatDist;
3063 #ifdef DEBUG_MANEUVER 3068 <<
" latDist=" << latDist
3069 <<
" maneuverDist=" << maneuverDist
3072 <<
" fullLatDist=" << fullLatDist
3073 <<
" speedAccel=" << speedAccel
3074 <<
" speedDecel=" << speedDecel
3075 <<
" speedBound=" << speedBound
3079 if (speedDecel * speedAccel <= 0 && (
3081 (latDist >= 0 && speedAccel >= speedBound && speedBound >= speedDecel)
3082 || (latDist <= 0 && speedAccel <= speedBound && speedBound <= speedDecel))) {
3084 #ifdef DEBUG_MANEUVER 3086 std::cout <<
" computeSpeedLat a)\n";
3093 #ifdef DEBUG_MANEUVER 3095 std::cout <<
" computeSpeedLat b)\n";
3098 return speedAccelSafe;
3102 if ((fabs(minDistAccel) < fabs(fullLatDist)) || (fabs(minDistAccel - fullLatDist) <
NUMERICAL_EPS)) {
3103 #ifdef DEBUG_MANEUVER 3105 std::cout <<
" computeSpeedLat c)\n";
3110 #ifdef DEBUG_MANEUVER 3112 std::cout <<
" minDistAccel=" << minDistAccel <<
"\n";
3117 if ((fabs(minDistCurrent) < fabs(fullLatDist)) || (fabs(minDistCurrent - fullLatDist) <
NUMERICAL_EPS)) {
3118 #ifdef DEBUG_MANEUVER 3120 std::cout <<
" computeSpeedLat d)\n";
3127 #ifdef DEBUG_MANEUVER 3129 std::cout <<
" computeSpeedLat e)\n";
3132 return speedDecelSafe;
3141 double maneuverDist) {
3144 double secondsToLeaveLane;
3154 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3170 double nextLeftSpace;
3171 if (nextActionStepSpeed > 0.) {
3186 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3190 <<
" avoidArrivalSpeed=" << avoidArrivalSpeed
3193 <<
"\n nextLeftSpace=" << nextLeftSpace
3194 <<
" nextActionStepSpeed=" << nextActionStepSpeed
3195 <<
" nextActionStepRemainingSeconds=" << secondsToLeaveLane - timeTillActionStep
3203 myCommittedSpeed = 0;
3205 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3209 <<
" secondsToLeave=" << secondsToLeaveLane
3211 <<
" committed=" << myCommittedSpeed
3231 const double vehWidth =
getWidth();
3233 const double leftVehSide = rightVehSide + vehWidth;
3234 const double rightVehSideDest = rightVehSide + latDist;
3235 const double leftVehSideDest = leftVehSide + latDist;
3236 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3238 std::cout <<
" commitFollowSpeed" 3239 <<
" latDist=" << latDist
3240 <<
" foeOffset=" << foeOffset
3241 <<
" vehRight=" << rightVehSide
3242 <<
" vehLeft=" << leftVehSide
3243 <<
" destRight=" << rightVehSideDest
3244 <<
" destLeft=" << leftVehSideDest
3250 if (vehDist.first != 0) {
3251 const MSVehicle* leader = vehDist.first;
3253 double foeRight, foeLeft;
3255 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3257 std::cout <<
" foe=" << vehDist.first->getID()
3258 <<
" gap=" << vehDist.second
3260 <<
" foeRight=" << foeRight
3261 <<
" foeLeft=" << foeLeft
3262 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
3263 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
3267 if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
3271 speed =
MIN2(speed, vSafe);
3272 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3274 std::cout <<
" case1 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3277 }
else if (
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)) {
3282 speed =
MIN2(speed, vSafe);
3283 #if defined(DEBUG_MANEUVER) || defined(DEBUG_COMMITTED_SPEED) 3285 std::cout <<
" case2 vsafe=" << vSafe <<
" speed=" << speed <<
"\n";
3381 const std::pair<MSVehicle*, double>& leader,
3382 const std::pair<MSVehicle*, double>& neighLead,
3383 const std::pair<MSVehicle*, double>& neighFollow,
3385 const std::vector<MSVehicle::LaneQ>& preb,
3391 #ifdef DEBUG_WANTSCHANGE 3393 std::cout <<
"\nWANTS_CHANGE\n" <<
SIMTIME 3400 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3414 double maneuverDist;
3417 leaders, followers, blockers,
3418 neighLeaders, neighFollowers, neighBlockers,
3420 lastBlocked, firstBlocked, latDist, maneuverDist, blocked);
3426 result |=
getLCA(result, latDist);
3428 #if defined(DEBUG_WANTSCHANGE) || defined(DEBUG_STATE) 3433 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
3434 << ((result &
LCA_URGENT) ?
" (urgent)" :
"")
3440 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
void * inform(void *info, MSVehicle *sender)
The link is a partial left direction.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
static double gLateralResolution
void initDerivedParameters()
init cached parameters derived directly from model parameters
const std::vector< double > getSubLaneSides() const
Returns the right side offsets of this edge's sublanes.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i...
saves leader/follower vehicles and their distances relative to an ego vehicle
double myChangeProbThresholdLeft
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
void msg(const CLeaderDist &cld, double speed, int state)
send a speed recommendation to the given vehicle
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key ...
double mySpeedGainProbabilityLeft
a value for tracking the probability that a change to the left is beneficial
The action is due to the default of keeping right "Rechtsfahrgebot".
double myLastLateralGapRight
The action is done to help someone else.
#define RELGAIN_NORMALIZATION_MIN_SPEED
std::set< const MSVehicle * > myCFRelated
set of vehicles that are in a car-following relationship with ego (leader of followers) ...
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
virtual std::string toString() const
print a debugging representation
#define ROUNDABOUT_DIST_BONUS
int myPreviousState
lane changing state from the previous simulation step
double informLeaders(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds)
MSLane * getLane() const
Returns the lane the vehicle is on.
bool myCanChangeFully
whether the current lane changing maneuver can be finished in a single step
double computeGapFactor(int state) const
compute the gap factor for the given state
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
The vehicle is blocked by left follower.
At the leftmost side of the lane.
int gPrecision
the precision for floating point outputs
LateralAlignment getPreferredLateralAlignment() const
Get vehicle's preferred lateral alignment.
double getManeuverDist() const
Returns the remaining unblocked distance for the current maneuver. (only used by sublane model) ...
int checkBlockingVehicles(const MSVehicle *ego, const MSLeaderDistanceInfo &vehicles, double latDist, double foeOffset, bool leaders, LaneChangeAction blockType, double &safeLatGapRight, double &safeLatGapLeft, std::vector< CLeaderDist > *collectBlockers=0) const
check whether any of the vehicles overlaps with ego
const double SUMO_const_laneWidth
static int lowest_bit(int changeReason)
return the most important change reason
The car-following model abstraction.
double computeSpeedLat(double latDist, double &maneuverDist)
decides the next lateral speed depending on the remaining lane change distance to be covered and upda...
int checkBlocking(const MSLane &neighLane, double &latDist, double &maneuverDist, int laneOffset, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, std::vector< CLeaderDist > *collectLeadBlockers=0, std::vector< CLeaderDist > *collectFollowBlockers=0, bool keepLatGapManeuver=false, double gapFactor=0, int *retBlockedFully=0)
restrict latDist to permissible speed and determine blocking state depending on that distance ...
double getPositionOnLane() const
Get the vehicle's position along the lane.
double mySpeedLossProbThreshold
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
void setOwnState(const int state)
static CLeaderDist getSlowest(const MSLeaderDistanceInfo &ldi)
get the slowest vehicle in the given info
int getBestLaneOffset() const
The link is a 180 degree turn.
double myPreviousManeuverDist
Maneuver distance from the previous simulation step.
ArrivalPosLatDefinition arrivalPosLatProcedure
Information how the vehicle shall choose the lateral arrival position.
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
double arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
std::vector< double > myExpectedSublaneSpeeds
expected travel speeds on all sublanes on the current edge(!)
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
double myTimeToImpatience
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
double getLength() const
Returns the lane's length.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const MSRoute & getRoute() const
Returns the current route.
double getMinGapLat() const
Get the minimum lateral gap that vehicles of this type maintain.
static double avoidArrivalAccel(double dist, double time, double speed, double maxDecel)
Computes the acceleration needed to arrive not before the given time.
double myMaxSpeedLatStanding
const MSEdge * getLastEdge() const
returns the destination edge
static const double NO_NEIGHBOR
const std::string & getID() const
Returns the id.
bool sameDirection(const StateAndDist &other) const
align with the closest sublane border
double length
The overall length which may be driven when using this lane without a lane change.
bool debugVehicle() const
whether the current vehicles shall be debugged
The action is due to the wish to be faster (tactical lc)
double getWidth() const
Returns the lane's width.
#define UNUSED_PARAMETER(x)
MSLCM_SL2015(MSVehicle &v)
used by the sublane model
#define LCA_RIGHT_IMPATIENCE
The link is a (hard) left direction.
double myTurnAlignmentDist
LateralAlignment
Numbers representing special SUMO-XML-attribute values Information how vehicles align themselves with...
double myChangeProbThresholdRight
MSAbstractLaneChangeModel & getLaneChangeModel()
int keepLatGap(int state, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, int laneOffset, double &latDist, double &maneuverDist, int &blocked)
check whether lateral gap requirements are met override the current maneuver if necessary ...
#define MAX_ONRAMP_LENGTH
#define GAIN_PERCEPTION_THRESHOLD
#define ARRIVALPOS_LAT_THRESHOLD
The link is a straight direction.
double mySafeLatDistRight
the lateral distance the vehicle can safely move in the currently considered direction ...
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Needs to stay on the current lane.
void saveBlockerLength(const MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
const LaneChangeModel myModel
the type of this model
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
double getWidth() const
return the widht of this vehicle (padded for numerical stability)
static bool overlap(double right, double left, double right2, double left2)
return whether the given intervals overlap
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
A class responsible for exchanging messages between cars involved in lane-change interaction.
StateAndDist decideDirection(StateAndDist sd1, StateAndDist sd2) const
decide in which direction to move in case both directions are desirable
A road/street connecting two junctions.
void commitManoeuvre(int blocked, int blockedFully, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, const MSLane &neighLane, double maneuverDist)
commit to lane change maneuvre potentially overriding safe speed
double myLeadingBlockerLength
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
int getIndex() const
Returns the lane's index.
double getActionStepLengthSecs() const
Returns the vehicle's action step length in secs, i.e. the interval between two action points...
double myManeuverDist
The complete lateral distance the vehicle wants to travel to finish its maneuver Only used by sublane...
double commitFollowSpeed(double speed, double latDist, double secondsToLeaveLane, const MSLeaderDistanceInfo &leaders, double foeOffset) const
compute speed when committing to an urgent change that is safe in regard to leading vehicles ...
blocked in all directions
void updateCFRelated(const MSLeaderDistanceInfo &vehicles, double foeOffset, bool leaders)
find leaders/followers that are already in a car-following relationship with ego
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane ...
The action is urgent (to be defined by lc-model)
virtual double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
static double brakeGapEuler(const double speed, const double decel, const double headwayTime)
At the center of the lane.
static MSPModel * getModel()
void addLCSpeedAdvice(const double vSafe)
Takes a vSafe (speed advice for speed in the next simulation step), converts it into an acceleration ...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
const MSEdge * myLastEdge
expected travel speeds on all sublanes on the current edge(!)
double informLeader(int blocked, int dir, const CLeaderDist &neighLead, double remainingSeconds)
static LaneChangeAction getLCA(int state, double latDist)
compute lane change action from desired lateral distance
void informFollowers(int blocked, int dir, const std::vector< CLeaderDist > &blockers, double remainingSeconds, double plannedSpeed)
call informFollower for multiple followers
double myMaxSpeedLatFactor
double getEmergencyDecel() const
Get the vehicle type's maximal phisically possible deceleration [m/s^2].
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
double getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0) ...
const std::pair< double, LinkDirection > & getNextTurn()
Get the distance and direction of the next upcoming turn for the vehicle (within its look-ahead range...
int wantsChangeSublane(int laneOffset, LaneChangeAction alternatives, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked, double &latDist, double &maneuverDist, int &blocked)
Called to examine whether the vehicle wants to change with the given laneOffset (using the sublane mo...
At the rightmost side of the lane.
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
#define KEEP_RIGHT_ACCEPTANCE
The link is a (hard) right direction.
The action is needed to follow the route (navigational lc)
int _wantsChangeSublane(int laneOffset, LaneChangeAction alternatives, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &followers, const MSLeaderDistanceInfo &blockers, const MSLeaderDistanceInfo &neighLeaders, const MSLeaderDistanceInfo &neighFollowers, const MSLeaderDistanceInfo &neighBlockers, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked, double &latDist, double &maneuverDist, int &blocked)
helper function for doing the actual work
A structure representing the best lanes for continuing the current route starting at 'lane'...
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0 ...
bool hasInfluencer() const
virtual void updateSafeLatDist(const double travelledLatDist)
Updates the value of safe lateral distances (mySafeLatDistLeft and mySafeLatDistRight) during maneuve...
double getMinGap() const
Get the free space in front of vehicles of this class.
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
int myOwnState
The current state of the vehicle.
maintain the current alignment
bool isInternal() const
return whether this edge is an internal edge
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
#define LOOK_AHEAD_SPEED_MEMORY
#define LOOK_AHEAD_MIN_SPEED
static CLeaderDist getLongest(const MSLeaderDistanceInfo &ldi)
get the longest vehicle in the given info
The link is a partial right direction.
bool cancelRequest(int state, int laneOffset)
whether the influencer cancels the given request
const MSLane * lane
The lane to stop at.
double myCooperativeParam
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getRightSideOnEdge() const
static double gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1=0, double a2=0, const double maxV1=std::numeric_limits< double >::max(), const double maxV2=std::numeric_limits< double >::max())
return the resulting gap if, starting with gap currentGap, two vehicles continue with constant accele...
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
double computeSpeedGain(double latDistSublane, double defaultNextSpeed) const
compute speedGain when moving by the given amount
int getRightmostSublane() const
std::pair< const MSPerson *, double > PersonDist
int checkStrategicChange(int ret, int laneOffset, const std::vector< MSVehicle::LaneQ > &preb, const MSLeaderDistanceInfo &leaders, const MSLeaderDistanceInfo &neighLeaders, int currIdx, int bestLaneOffset, bool changeToBest, double currentDist, double neighDist, double laDist, int roundaboutEdgesAhead, double latLaneDist, double &latDist)
compute strategic lane change actions TODO: Better documentation, refs #2
bool hasStoppedVehicle() const
whether a stopped vehicle is leader
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
std::pair< const MSVehicle *, double > CLeaderDist
Influencer & getInfluencer()
Returns the velocity/lane influencer.
LaneChangeAction
The state of a vehicle's lane-change behavior.
virtual void setOwnState(const int state)
virtual void setMaxDecel(double decel)
Sets a new value for maximal comfortable deceleration [m/s^2].
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
Called to adapt the speed in order to allow a lane change. It uses information on LC-related desired ...
#define SPEEDGAIN_MEMORY_FACTOR
bool isActive() const
Returns whether the current simulation step is an action point for the vehicle.
double myKeepRightProbability
The vehicle is blocked being overlapping.
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
std::vector< MSLane * > bestContinuations
void getSublaneBorders(int sublane, double latOffset, double &rightSide, double &leftSide) const
static double estimateArrivalTime(double dist, double speed, double maxSpeed, double accel)
Computes the time needed to travel a distance dist given an initial speed and constant acceleration...
int & getCanceledState(const int dir)
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
void informFollower(int blocked, int dir, const CLeaderDist &neighFollow, double remainingSeconds, double plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
double mySpeedLat
the current lateral speed
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
No information given; use default.
double getLength() const
Get vehicle's length [m].
#define SPEEDGAIN_DECAY_FACTOR
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
align with the rightmost sublane that allows keeping the current speed
virtual void prepareStep()
bool allowsVehicleClass(SUMOVehicleClass vclass) const
std::vector< double > myLCAccelerationAdvices
vector of LC-related acceleration recommendations Filled in wantsChange() and applied in patchSpeed()...
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
#define CUT_IN_LEFT_SPEED_THRESHOLD
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key ...
The action is due to a TraCI request.
The link is a 180 degree turn (left-hand network)
virtual double followSpeedTransient(double duration, const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle's follow speed that avoids a collision for the given amount of time...
#define HELP_DECEL_FACTOR
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
double mySpeedGainProbabilityRight
a value for tracking the probability that a change to the right is beneficial
#define LATGAP_SPEED_THRESHOLD2
static bool gSemiImplicitEulerUpdate
double myCommittedSpeed
the speed when committing to a change maneuver
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
bool ignoreOverlap() const
bool myDontBrake
flag to prevent speed adaptation by slowing down
#define LATGAP_SPEED_THRESHOLD
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
double getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0) ...
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
virtual double getArrivalPos() const
Returns this vehicle's desired arrivalPos for its current route (may change on reroute) ...
double getSpeed() const
Returns the vehicle's current speed.
The vehicle is blocked by right leader.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
double myLastLateralGapLeft
the minimum lateral gaps to other vehicles that were found when last changing to the left and right ...
double getLatDist() const
public emergency vehicles
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, double > &leader, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
Called to examine whether the vehicle wants to change using the given laneOffset (this is a wrapper a...
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle's follow speed (no dawdling)
const std::string & getID() const
Returns the name of the vehicle.
Representation of a lane in the micro simulation.
const MSCFModel & myCarFollowModel
The vehicle's car following model.
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
The vehicle is blocked by right follower.
int computeSublaneShift(const MSEdge *prevEdge, const MSEdge *curEdge)
compute shift so that prevSublane + shift = newSublane
Interface for lane-change models.
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling) ...
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
void updateExpectedSublaneSpeeds(const MSLeaderDistanceInfo &ahead, int sublaneOffset, int laneIndex)
update expected speeds for each sublane of the current edge
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
void updateGaps(const MSLeaderDistanceInfo &others, double foeOffset, double oldCenter, double gapFactor, double &surplusGapRight, double &surplusGapLeft, bool saveMinGap=false, double netOverlap=0, double latDist=0, std::vector< CLeaderDist > *collectBlockers=0)
check remaining lateral gaps for the given foe vehicles and optionally update minimum lateral gaps ...
The link has no direction (is a dead end link)
#define SPEED_GAIN_MIN_SECONDS
bool amBlockingFollowerPlusNB()
double getWidth() const
Returns the edges's width (sum over all lanes)