46 #define LOOK_FORWARD_SPEED_DIVIDER (double)14. 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 64 #define LOOK_AHEAD_SPEED_DECREMENT 6. 66 #define HELP_DECEL_FACTOR (double)1.0 68 #define HELP_OVERTAKE (double)(10.0 / 3.6) 69 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 71 #define KEEP_RIGHT_HEADWAY (double)2.0 73 #define URGENCY (double)2.0 75 #define ROUNDABOUT_DIST_BONUS (double)100.0 77 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 78 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 80 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 82 #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 83 #define GAIN_PERCEPTION_THRESHOLD 0.05 // the minimum relative speed gain which affects the behavior 85 #define SPEED_GAIN_MIN_SECONDS 20.0 87 #define ARRIVALPOS_LAT_THRESHOLD 100.0 90 #define LATGAP_SPEED_THRESHOLD (50 / 3.6) 94 #define DEBUG_COND (myVehicle.isSelected()) 106 mySpeedGainProbabilityRight(0),
107 mySpeedGainProbabilityLeft(0),
108 myKeepRightProbability(0),
109 myLeadingBlockerLength(0),
113 myCanChangeFully(true),
123 myChangeProbThresholdRight(2.0 * myKeepRightParam /
MAX2(
NUMERICAL_EPS, mySpeedGainParam)),
125 mySpeedLossProbThreshold(-0.01 + (1 - mySublaneParam)) {
149 const std::vector<MSVehicle::LaneQ>& preb,
152 double& latDist,
int& blocked) {
155 const std::string changeType = laneOffset == -1 ?
"right" : (laneOffset == 1 ?
"left" :
"current");
166 <<
" considerChangeTo=" << changeType
171 leaders, followers, blockers,
172 neighLeaders, neighFollowers, neighBlockers,
174 lastBlocked, firstBlocked, latDist, blocked);
176 result =
keepLatGap(result, leaders, followers, blockers,
177 neighLeaders, neighFollowers, neighBlockers,
178 neighLane, laneOffset, latDist, blocked);
180 result |=
getLCA(result, latDist);
186 <<
" latDist=" << latDist
194 <<
" wantsNoChangeTo=" << changeType
214 std::cout <<
" myCanChangeFully=true\n";
224 const double newSpeed =
_patchSpeed(min, wanted, max, cfModel);
226 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
232 <<
" wanted=" << wanted
249 double MAGIC_offset = 1.;
262 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
264 return MAX2(min, safe);
269 double nVSafe = wanted;
271 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
273 if (v >= min && v <= max) {
274 nVSafe =
MIN2(v, nVSafe);
277 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" got nVSafe=" << nVSafe <<
"\n";
282 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
286 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
294 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" got vSafe\n";
305 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_WANTS_LANECHANGE (strat, no vSafe)\n";
307 return (max + wanted) / (double) 2.0;
312 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_BLOCKED_BY_LEADER (coop)\n";
314 return (min + wanted) / (double) 2.0;
318 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_BLOCKED_BY_FOLLOWER (coop)\n";
320 return (max + wanted) / (double) 2.0;
362 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_AMBLOCKINGLEADER\n";
364 return (max + wanted) / (double) 2.0;
369 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_AMBLOCKINGFOLLOWER_DONTBRAKE\n";
386 if (pinfo->first >= 0) {
394 <<
" informedBy=" << sender->
getID()
395 <<
" info=" << pinfo->second
396 <<
" vSafe=" << pinfo->first
406 assert(cld.first != 0);
415 double remainingSeconds) {
418 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
421 plannedSpeed =
MIN2(plannedSpeed, v);
425 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
429 assert(neighLead.first != 0);
431 if (
gDebugFlag2) std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 434 const double dv = plannedSpeed - nv->
getSpeed();
435 const double overtakeDist = (neighLead.second
447 || dv * remainingSeconds < overtakeDist) {
461 <<
" cannot overtake leader nv=" << nv->
getID()
463 <<
" remainingSeconds=" << remainingSeconds
464 <<
" targetSpeed=" << targetSpeed
465 <<
" nextSpeed=" << nextSpeed
474 <<
" cannot overtake fast leader nv=" << nv->
getID()
476 <<
" remainingSeconds=" << remainingSeconds
477 <<
" targetSpeed=" << targetSpeed
486 <<
" wants to overtake leader nv=" << nv->
getID()
488 <<
" remainingSeconds=" << remainingSeconds
489 <<
" currentGap=" << neighLead.second
491 <<
" overtakeDist=" << overtakeDist
500 }
else if (neighLead.first != 0) {
509 std::cout <<
" not blocked by leader nv=" << nv->
getID()
511 <<
" gap=" << neighLead.second
512 <<
" nextGap=" << neighLead.second - dv
514 <<
" targetSpeed=" << targetSpeed
517 return MIN2(targetSpeed, plannedSpeed);
529 double remainingSeconds,
530 double plannedSpeed) {
532 assert(neighFollow.first != 0);
534 if (
gDebugFlag2) std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 540 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
542 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
560 const double neighNewSpeed1s =
MAX2(0., nv->
getSpeed() - helpDecel);
561 const double dv = plannedSpeed - neighNewSpeed1s;
563 const double decelGap = neighFollow.second + dv;
568 <<
" egoNV=" << plannedSpeed
569 <<
" nvNewSpeed=" << neighNewSpeed
570 <<
" nvNewSpeed1s=" << neighNewSpeed1s
571 <<
" deltaGap=" << dv
572 <<
" decelGap=" << decelGap
573 <<
" secGap=" << secureGap
576 if (decelGap > 0 && decelGap >= secureGap) {
590 std::cout <<
" wants to cut in before nv=" << nv->
getID()
591 <<
" vsafe1=" << vsafe1
592 <<
" vsafe=" << vsafe
596 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap +
POSITION_EPS)) {
600 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
606 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
620 std::cout <<
" wants right follower to slow down a bit\n";
624 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
632 const double overtakeDist = (neighFollow.second
638 const double needDV = overtakeDist / remainingSeconds;
645 <<
" wants to be overtaken by=" << nv->
getID()
646 <<
" overtakeDist=" << overtakeDist
648 <<
" vhelp=" << vhelp
649 <<
" needDV=" << needDV
654 }
else if (neighFollow.first != 0) {
663 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
670 const std::vector<CLeaderDist>& blockers,
671 double remainingSeconds) {
673 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
674 plannedSpeed =
MIN2(plannedSpeed,
informLeader(blocked, dir, *it, remainingSeconds));
682 const std::vector<CLeaderDist>& blockers,
683 double remainingSeconds,
684 double plannedSpeed) {
685 for (std::vector<CLeaderDist>::const_iterator it = blockers.begin(); it != blockers.end(); ++it) {
686 informFollower(blocked, dir, *it, remainingSeconds, plannedSpeed);
711 std::vector<double> newExpectedSpeeds;
716 const std::vector<MSLane*>& lanes = currEdge->
getLanes();
717 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
719 for (
int i = 0; i < subLanes; ++i) {
720 newExpectedSpeeds.push_back((*it_lane)->getVehicleMaxSpeed(&
myVehicle));
730 const int newI = i + subLaneShift;
731 if (newI > 0 && newI < (
int)newExpectedSpeeds.size()) {
749 const std::vector<MSLane*>& lanes = prevEdge->
getLanes();
750 for (std::vector<MSLane*>::const_iterator it_lane = lanes.begin(); it_lane != lanes.end(); ++it_lane) {
751 const MSLane* lane = *it_lane;
752 for (MSLinkCont::const_iterator it_link = lane->
getLinkCont().begin(); it_link != lane->
getLinkCont().end(); ++it_link) {
753 if (&((*it_link)->getLane()->getEdge()) == curEdge) {
755 const MSLane* target = (*it_link)->getLane();
756 const std::vector<MSLane*>& lanes2 = curEdge->
getLanes();
757 for (std::vector<MSLane*>::const_iterator it_lane2 = lanes2.begin(); it_lane2 != lanes2.end(); ++it_lane2) {
758 const MSLane* lane2 = *it_lane2;
759 if (lane2 == target) {
760 return prevShift + curShift;
815 const std::vector<MSVehicle::LaneQ>& preb,
818 double& latDist,
int& blocked) {
823 int bestLaneOffset = 0;
824 double currentDist = 0;
825 double neighDist = 0;
832 for (
int p = 0; p < (int) preb.size(); ++p) {
833 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
834 assert(p + laneOffset < (
int)preb.size());
836 neigh = preb[p + laneOffset];
837 currentDist = curr.
length;
839 bestLaneOffset = curr.bestLaneOffset;
841 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
845 <<
" bestLaneOffsetOld=" << bestLaneOffset
846 <<
" bestLaneOffsetNew=" << laneOffset
849 bestLaneOffset = laneOffset;
856 const bool right = (laneOffset == -1);
857 const bool left = (laneOffset == 1);
861 const bool changeToBest = (right && bestLaneOffset < 0) || (left && bestLaneOffset > 0) || (laneOffset == 0 && bestLaneOffset == 0);
871 double leftLimit = halfCurrentLaneWidth - halfVehWidth - latPos;
872 double rightLimit = -halfCurrentLaneWidth + halfVehWidth - latPos;
873 double latLaneDist = 0;
874 if (laneOffset == -1) {
877 }
else if (laneOffset == 1) {
903 <<
" leaders=" << leaders.
toString()
904 <<
" followers=" << followers.
toString()
905 <<
" blockers=" << blockers.
toString()
906 <<
" neighLeaders=" << neighLeaders.
toString()
907 <<
" neighFollowers=" << neighFollowers.
toString()
908 <<
" neighBlockers=" << neighBlockers.
toString()
909 <<
" changeToBest=" << changeToBest
910 <<
" latLaneDist=" << latLaneDist
911 <<
" leftLimit=" << leftLimit
912 <<
" rightLimit=" << rightLimit
919 if (lastBlocked != firstBlocked) {
967 int roundaboutEdgesAhead = 0;
969 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
970 roundaboutEdgesAhead += 1;
971 }
else if (roundaboutEdgesAhead > 0) {
976 int roundaboutEdgesAheadNeigh = 0;
978 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
979 roundaboutEdgesAheadNeigh += 1;
980 }
else if (roundaboutEdgesAheadNeigh > 0) {
985 if (roundaboutEdgesAhead > 1) {
989 if (roundaboutEdgesAhead > 0) {
991 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
995 if (laneOffset != 0) {
1008 roundaboutEdgesAhead,
1013 if ((ret &
LCA_STAY) != 0 && latDist == 0) {
1020 if (changeToBest &&
abs(bestLaneOffset) > 1) {
1024 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1032 if (*firstBlocked != neighLeadLongest) {
1035 std::vector<CLeaderDist> collectLeadBlockers;
1036 std::vector<CLeaderDist> collectFollowBlockers;
1039 leaders, followers, blockers,
1040 neighLeaders, neighFollowers, neighBlockers, &collectLeadBlockers, &collectFollowBlockers);
1042 const double absLaneOffset = fabs(bestLaneOffset != 0 ? bestLaneOffset : latDist /
SUMO_const_laneWidth);
1043 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1046 const double plannedSpeed =
informLeaders(blocked, myLca, collectLeadBlockers, remainingSeconds);
1048 if (plannedSpeed >= 0) {
1050 informFollowers(blocked, myLca, collectFollowBlockers, remainingSeconds, plannedSpeed);
1057 <<
" remainingSeconds=" << remainingSeconds
1058 <<
" plannedSpeed=" << plannedSpeed
1065 if (roundaboutEdgesAhead > 1) {
1074 if ((ret & LCA_STAY) == 0) {
1075 latDist = latLaneDist;
1077 leaders, followers, blockers,
1078 neighLeaders, neighFollowers, neighBlockers);
1093 const double inconvenience = (latLaneDist < 0
1106 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1108 << (((
myOwnState & myLcaCounter) != 0) ?
" (counter)" :
"")
1114 latDist = latLaneDist;
1116 leaders, followers, blockers,
1117 neighLeaders, neighFollowers, neighBlockers);
1143 const double leftVehSide = rightVehSide + vehWidth;
1147 int leftmostOnEdge = (int)sublaneSides.size() - 1;
1148 while (leftmostOnEdge > 0 && sublaneSides[leftmostOnEdge] > leftVehSide) {
1151 int rightmostOnEdge = leftmostOnEdge;
1152 while (rightmostOnEdge > 0 && sublaneSides[rightmostOnEdge] > rightVehSide +
NUMERICAL_EPS) {
1155 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1158 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1164 std::cout <<
" adapted to current sublane=" << rightmostOnEdge <<
" defaultNextSpeed=" << defaultNextSpeed <<
"\n";
1167 std::cout <<
" sublaneSides[rightmostOnEdge]=" << sublaneSides[rightmostOnEdge] <<
" rightVehSide=" << rightVehSide <<
"\n";
1175 const double leftMax =
MAX2(
1178 assert(leftMax <= edge.
getWidth());
1179 int sublaneCompact =
MAX2(iMin, rightmostOnEdge - 1);
1182 <<
" checking sublanes rightmostOnEdge=" << rightmostOnEdge
1183 <<
" leftmostOnEdge=" << leftmostOnEdge
1185 <<
" leftMax=" << leftMax
1186 <<
" sublaneCompact=" << sublaneCompact
1188 for (
int i = iMin; i < (int)sublaneSides.size(); ++i) {
1189 if (sublaneSides[i] + vehWidth < leftMax) {
1195 while (vMin > 0 && j < (
int)sublaneSides.size() && sublaneSides[j] < sublaneSides[i] + vehWidth) {
1203 maxGain = relativeGain;
1206 latDist = sublaneSides[i] - rightVehSide;
1208 std::cout <<
" i=" << i <<
" newLatDist=" << latDist <<
" relGain=" << relativeGain <<
"\n";
1213 std::cout <<
" i=" << i <<
" rightmostOnEdge=" << rightmostOnEdge <<
" vMin=" << vMin <<
" relGain=" << relativeGain <<
" sublaneCompact=" << sublaneCompact <<
"\n";
1216 maxGainRight =
MAX2(maxGainRight, relativeGain);
1217 }
else if (latDist > 0) {
1218 maxGainLeft =
MAX2(maxGainLeft, relativeGain);
1220 const double subAlignDist = sublaneSides[i] - rightVehSide;
1221 if (fabs(subAlignDist) < fabs(latDistNice)) {
1222 latDistNice = subAlignDist;
1224 <<
" nicest sublane=" << i
1225 <<
" side=" << sublaneSides[i]
1226 <<
" rightSide=" << rightVehSide
1227 <<
" latDistNice=" << latDistNice
1250 <<
" defaultNextSpeed=" << defaultNextSpeed
1251 <<
" maxGain=" << maxGain
1252 <<
" maxGainRight=" << maxGainRight
1253 <<
" maxGainLeft=" << maxGainLeft
1254 <<
" latDist=" << latDist
1255 <<
" latDistNice=" << latDistNice
1256 <<
" sublaneCompact=" << sublaneCompact
1261 if (right && maxGain >= 0 && latDist <= 0) {
1268 double fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
1270 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
1271 fullSpeedGap =
MAX2(0.,
MIN2(fullSpeedGap,
1273 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
1274 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
1283 <<
" considering keepRight:" 1285 <<
" neighDist=" << neighDist
1287 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1289 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1290 <<
" acceptanceTime=" << acceptanceTime
1291 <<
" fullSpeedGap=" << fullSpeedGap
1292 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1293 <<
" dProb=" << deltaProb
1302 latDist = latLaneDist;
1304 leaders, followers, blockers,
1305 neighLeaders, neighFollowers, neighBlockers);
1314 <<
" latDist=" << latDist
1323 leaders, followers, blockers,
1324 neighLeaders, neighFollowers, neighBlockers);
1335 <<
" latDist=" << latDist
1336 <<
" stayInLane=" << stayInLane
1347 leaders, followers, blockers,
1348 neighLeaders, neighFollowers, neighBlockers);
1356 double latDistSublane = 0.;
1361 && bestLaneOffset == 0
1397 latDistSublane = latDistNice;
1400 latDistSublane = sublaneSides[sublaneCompact] - rightVehSide;
1411 <<
" latDist=" << latDist
1412 <<
" latDistSublane=" << latDistSublane
1424 && ((myOrigLatDist < 0 && latDistSublane > 0) || (
myOrigLatDist > 0 && latDistSublane < 0))) {
1427 latDist = latDistSublane;
1434 <<
" latDist=" << latDist
1439 leaders, followers, blockers,
1440 neighLeaders, neighFollowers, neighBlockers);
1482 if ((*blocked) != 0) {
1506 (*blocked)->getCarFollowModel().getMaxDecel()));
1546 <<
" potential=" << potential
1559 const MSLane* lane = lanes[laneIndex];
1561 assert(preb.size() == lanes.size());
1563 for (
int sublane = 0; sublane < (int)ahead.
numSublanes(); ++sublane) {
1564 const int edgeSublane = sublane + sublaneOffset;
1568 const MSVehicle* leader = ahead[sublane];
1578 const double memoryFactor = 0.5;
1592 double maxLength = -1;
1594 if (ldi[i].first != 0) {
1595 const double length = ldi[i].first->getVehicleType().getLength();
1596 if (length > maxLength) {
1611 if (ldi[i].first != 0) {
1612 const double speed = ldi[i].first->getSpeed();
1613 if (speed < minSpeed) {
1631 std::vector<CLeaderDist>* collectLeadBlockers,
1632 std::vector<CLeaderDist>* collectFollowBlockers,
1633 bool keepLatGapManeuver) {
1635 if (!keepLatGapManeuver) {
1639 latDist =
MAX2(
MIN2(latDist, maxDist), -maxDist);
1644 double surplusGapRight =
MIN2(maxDist, center - halfWidth);
1648 if (laneOffset != 0) {
1653 std::cout <<
" checkBlocking latDist=" << latDist <<
" surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
1659 latDist =
MAX2(latDist, -surplusGapRight);
1665 latDist =
MIN2(latDist, surplusGapLeft);
1682 if (laneOffset != 0) {
1696 if (laneOffset != 0) {
1703 if (collectFollowBlockers != 0 && collectLeadBlockers != 0) {
1705 for (std::vector<CLeaderDist>::const_iterator it2 = collectLeadBlockers->begin(); it2 != collectLeadBlockers->end(); ++it2) {
1706 for (std::vector<CLeaderDist>::iterator it = collectFollowBlockers->begin(); it != collectFollowBlockers->end();) {
1707 if ((*it2).first == (*it).first) {
1709 std::cout <<
" removed follower " << (*it).first->getID() <<
" because it is already a leader\n";
1711 it = collectFollowBlockers->erase(it);
1725 double latDist,
double foeOffset,
bool leaders,
LaneChangeAction blockType,
1726 std::vector<CLeaderDist>* collectBlockers)
const {
1730 const double leftVehSide = rightVehSide + vehWidth;
1731 const double rightVehSideDest = rightVehSide + latDist;
1732 const double leftVehSideDest = leftVehSide + latDist;
1733 const double rightNoOverlap =
MIN2(rightVehSideDest, rightVehSide);
1734 const double leftNoOverlap =
MAX2(leftVehSideDest, leftVehSide);
1736 std::cout <<
" checkBlocking" 1737 <<
" latDist=" << latDist
1738 <<
" foeOffset=" << foeOffset
1739 <<
" vehRight=" << rightVehSide
1740 <<
" vehLeft=" << leftVehSide
1741 <<
" rightNoOverlap=" << rightNoOverlap
1742 <<
" leftNoOverlap=" << leftNoOverlap
1743 <<
" destRight=" << rightVehSideDest
1744 <<
" destLeft=" << leftVehSideDest
1745 <<
" leaders=" << leaders
1749 for (
int i = 0; i < vehicles.
numSublanes(); ++i) {
1751 if (vehDist.first != 0) {
1752 const MSVehicle* leader = vehDist.first;
1755 std::swap(leader, follower);
1758 double foeRight, foeLeft;
1761 std::cout <<
" foe=" << vehDist.first->getID()
1762 <<
" gap=" << vehDist.second
1764 <<
" foeRight=" << foeRight
1765 <<
" foeLeft=" << foeLeft
1766 <<
" overlapBefore=" <<
overlap(rightVehSide, leftVehSide, foeRight, foeLeft)
1767 <<
" overlap=" <<
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft)
1768 <<
" overlapDest=" <<
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)
1775 if (
overlap(rightNoOverlap, leftNoOverlap, foeRight, foeLeft)) {
1776 if (vehDist.second < 0) {
1778 std::cout <<
" overlap\n";
1781 if (collectBlockers == 0) {
1784 collectBlockers->push_back(vehDist);
1786 }
else if (
overlap(rightVehSideDest, leftVehSideDest, foeRight, foeLeft)) {
1794 if (vehDist.second < secureGap) {
1796 std::cout <<
" blocked by " << vehDist.first->getID() <<
" gap=" << vehDist.second <<
" secGap=" << secureGap <<
" decelFactor=" << decelFactor <<
"\n";
1798 result |= blockType;
1799 if (collectBlockers == 0) {
1802 collectBlockers->push_back(vehDist);
1816 assert(right <= left);
1817 assert(right2 <= left2);
1825 if (sd1.
state == 0) {
1827 }
else if (sd2.
state == 0) {
1840 <<
" dir1=" << sd1.
dir 1844 <<
" dir2=" << sd2.
dir 1851 return (!can1 && can2 && sd1.
sameDirection(sd2)) ? sd2 : sd1;
1855 return (!can2 && can1 && sd1.
sameDirection(sd2)) ? sd1 : sd2;
1863 }
else if (sd2.
dir == 0) {
1871 return can1 ? sd1 : sd2;
1894 const std::vector<MSVehicle::LaneQ>& preb,
1904 int roundaboutEdgesAhead,
1908 const bool right = (laneOffset == -1);
1909 const bool left = (laneOffset == 1);
1916 const double maxJam =
MAX2(preb[currIdx + laneOffset].occupation, preb[currIdx].occupation);
1923 <<
" laDist=" << laDist
1924 <<
" currentDist=" << currentDist
1925 <<
" usableDist=" << usableDist
1926 <<
" bestLaneOffset=" << bestLaneOffset
1927 <<
" best.length=" << best.
length 1928 <<
" maxJam=" << maxJam
1929 <<
" neighLeftPlace=" << neighLeftPlace
1933 if (laneOffset != 0 && changeToBest && bestLaneOffset == curr.
bestLaneOffset 1936 latDist = latLaneDist;
1955 <<
" avoid overtaking on the right nv=" << nv->
getID()
1958 <<
" plannedSpeed=" <<
myVSafes.back()
1972 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1975 }
else if (laneOffset != 0 && bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1981 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1986 && bestLaneOffset == 0
1989 && roundaboutEdgesAhead == 0
1995 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1999 && bestLaneOffset == 0
2006 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
2023 if (shadow == 0 || currentShadowDist >= requiredDist) {
2026 currentShadowDist += shadow->
getLength();
2031 if (currentShadowDist < requiredDist && currentShadowDist < usableDist) {
2042 if ((ret & lcaCounter) != 0) {
2047 std::cout <<
" reqAfterInfluence=" << ret <<
" ret=" << ret <<
"\n";
2099 const bool stayInLane = laneOffset == 0 || ((state &
LCA_STRATEGIC) != 0 && (state &
LCA_STAY) != 0);
2100 const double oldLatDist = latDist;
2109 double surplusGapRight = oldCenter - halfWidth;
2112 std::cout <<
" keepLatGap laneOffset=" << laneOffset
2113 <<
" latDist=" << latDist
2116 <<
" gapFactor=" << gapFactor
2117 <<
" stayInLane=" << stayInLane <<
"\n" 2118 <<
" stayInEdge: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2121 if (surplusGapLeft < 0 || surplusGapRight < 0) {
2131 if (laneOffset != 0) {
2137 std::cout <<
" minGapLat: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n" 2145 if (stayInLane || laneOffset == 1) {
2151 if (stayInLane || laneOffset == -1) {
2158 std::cout <<
" stayInLane: surplusGapRight=" << surplusGapRight <<
" surplusGapLeft=" << surplusGapLeft <<
"\n";
2161 if (surplusGapRight + surplusGapLeft < 0) {
2163 const double equalDeficit = 0.5 * (surplusGapLeft + surplusGapRight);
2164 if (surplusGapRight < surplusGapLeft) {
2166 const double delta =
MIN2(equalDeficit - surplusGapRight, physicalGapLeft);
2169 std::cout <<
" insufficient latSpace, move left: delta=" << delta <<
"\n";
2173 const double delta =
MIN2(equalDeficit - surplusGapLeft, physicalGapRight);
2176 std::cout <<
" insufficient latSpace, move right: delta=" << delta <<
"\n";
2181 latDist =
MAX2(
MIN2(latDist, surplusGapLeft), -surplusGapRight);
2192 std::cout <<
" wanted changeToLeft oldLatDist=" << oldLatDist <<
", blocked latGap changeToRight\n";
2194 latDist = oldLatDist;
2198 std::cout <<
" wanted changeToRight oldLatDist=" << oldLatDist <<
", blocked latGap changeToLeft\n";
2200 latDist = oldLatDist;
2207 std::cout <<
" latDistUpdated=" << (oldLatDist - latDist) <<
"\n";
2209 blocked =
checkBlocking(neighLane, latDist, laneOffset, leaders, followers, blockers, neighLeaders, neighFollowers, neighBlockers, 0, 0,
true);
2212 state = (state & ~LCA_STAY);
2215 std::cout <<
" latDist2=" << latDist
2232 if (others[i].first != 0 && others[i].second <= 0
2233 && (netOverlap == 0 || others[i].second + others[i].first->getVehicleType().getMinGap() < netOverlap)) {
2237 double foeRight, foeLeft;
2239 const double foeCenter = foeRight + 0.5 * res;
2240 const double gap =
MIN2(fabs(foeRight - oldCenter), fabs(foeLeft - oldCenter)) - halfWidth;
2244 <<
" foe=" << foe->
getID()
2245 <<
" foeRight=" << foeRight
2246 <<
" foeLeft=" << foeLeft
2247 <<
" oldCenter=" << oldCenter
2248 <<
" gap=" << others[i].second
2249 <<
" latgap=" << gap
2250 <<
" currentMinGap=" << currentMinGap
2251 <<
" surplusGapRight=" << surplusGapRight
2252 <<
" surplusGapLeft=" << surplusGapLeft
2259 if (foeCenter < oldCenter) {
2260 surplusGapRight =
MIN2(surplusGapRight, gap - currentMinGap);
2262 surplusGapLeft =
MIN2(surplusGapLeft, gap - currentMinGap);
2265 if (foeCenter < oldCenter) {
2267 std::cout <<
" new minimum rightGap=" << gap <<
"\n";
2272 std::cout <<
" new minimum leftGap=" << gap <<
"\n";
2335 const std::pair<MSVehicle*, double>& leader,
2336 const std::pair<MSVehicle*, double>& neighLead,
2337 const std::pair<MSVehicle*, double>& neighFollow,
2339 const std::vector<MSVehicle::LaneQ>& preb,
2343 #ifdef DEBUG_WANTS_CHANGE 2352 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
2367 leaders, followers, blockers,
2368 neighLeaders, neighFollowers, neighBlockers,
2370 lastBlocked, firstBlocked, latDist, blocked);
2376 result |=
getLCA(result, latDist);
2378 #ifdef DEBUG_WANTS_CHANGE 2383 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
2384 << ((result &
LCA_URGENT) ?
" (urgent)" :
"")
2390 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
void * inform(void *info, MSVehicle *sender)
const double mySpeedLossProbThreshold
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
static double gLateralResolution
const std::vector< double > getSubLaneSides() const
Returns the right side offsets of this edge's sublanes.
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time, assuming that during...
saves leader/follower vehicles and their distances relative to an ego vehicle
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
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
virtual std::string toString() const
print a debugging representation
#define ROUNDABOUT_DIST_BONUS
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 meneuver can be finished in a single step
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.
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)
const double myChangeProbThresholdLeft
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 getPositionOnLane() const
Get the vehicle's position along the lane.
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
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 arrivalPosLat
(optional) The lateral position the vehicle shall arrive on
std::vector< double > myExpectedSublaneSpeeds
expected travel speeds on all sublanes on the current edge(!)
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.
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 ...
const MSEdge * getLastEdge() const
returns the destination edge
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.
MSLCM_SL2015(MSVehicle &v)
used by the sublane model
#define LCA_RIGHT_IMPATIENCE
MSAbstractLaneChangeModel & getLaneChangeModel()
std::vector< double > myVSafes
speed adaptation requests by ego and surrounding vehicles
#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 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.
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.
double myLeadingBlockerLength
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
int getIndex() const
Returns the lane's index.
bool cancelRequest(int state)
whether the influencer cancels the given request
blocked in all directions
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)
At the center of the lane.
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 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) ...
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
void updateGaps(const MSLeaderDistanceInfo &others, double foeOffset, double oldCenter, double gapFactor, double &surplusGapRight, double &surplusGapLeft, bool saveMinGap=false, double netOverlap=0)
check remaining lateral gaps for the given foe vehicles and optionally update minimum lateral gaps ...
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 action is needed to follow the route (navigational lc)
double getImpatience() const
Returns this vehicles impatience.
A structure representing the best lanes for continuing the current route starting at 'lane'...
bool hasInfluencer() const
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 maximum deceleration [m/s^2].
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
int myOwnState
The current state of the vehicle.
maintain the current alignment
#define LOOK_AHEAD_SPEED_MEMORY
#define LOOK_AHEAD_MIN_SPEED
static CLeaderDist getLongest(const MSLeaderDistanceInfo &ldi)
get the longest vehicle in the given info
#define LOOK_FORWARD_RIGHT
double myCooperativeParam
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getRightSideOnEdge() const
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
int wantsChangeSublane(int laneOffset, 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...
int getRightmostSublane() const
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)
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.
double myKeepRightProbability
virtual double getHeadwayTime() const
Get the driver's reaction time [s].
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 getSublaneBorders(int sublane, double latOffset, double &rightSide, double &leftSide) const
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
static double _2double(const E *const data)
converts a char-type array into the double value described by it
No information given; use default.
double getLength() const
Get vehicle's length [m].
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
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
#define CUT_IN_LEFT_SPEED_THRESHOLD
const double myChangeProbThresholdRight
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.
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
#define HELP_DECEL_FACTOR
double mySpeedGainProbabilityRight
a value for tracking the probability that a change to the right is beneficial
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
int _wantsChangeSublane(int laneOffset, 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
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
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)
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 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)
restrict latDist to permissible speed and determine blocking state depending on that distance ...
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
The edge is an internal edge.
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...
static const double NO_LATERAL_NEIGHBOR
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.
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
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.
#define SPEED_GAIN_MIN_SECONDS
bool amBlockingFollowerPlusNB()
double getWidth() const
Returns the edges's width (sum over all lanes)