51 #define LOOK_FORWARD_SPEED_DIVIDER (double)14. 53 #define LOOK_FORWARD_RIGHT (double)10. 54 #define LOOK_FORWARD_LEFT (double)20. 56 #define JAM_FACTOR (double)1. 58 #define LCA_RIGHT_IMPATIENCE (double)-1. 59 #define CUT_IN_LEFT_SPEED_THRESHOLD (double)27. 61 #define LOOK_AHEAD_MIN_SPEED 0.0 62 #define LOOK_AHEAD_SPEED_MEMORY 0.9 63 #define LOOK_AHEAD_SPEED_DECREMENT 6. 65 #define HELP_DECEL_FACTOR (double)1.0 67 #define HELP_OVERTAKE (double)(10.0 / 3.6) 68 #define MIN_FALLBEHIND (double)(7.0 / 3.6) 70 #define RELGAIN_NORMALIZATION_MIN_SPEED (double)10.0 71 #define URGENCY (double)2.0 73 #define KEEP_RIGHT_TIME (double)5.0 // the number of seconds after which a vehicle should move to the right lane 74 #define KEEP_RIGHT_ACCEPTANCE (double)7.0 // calibration factor for determining the desire to keep right 75 #define ROUNDABOUT_DIST_BONUS (double)100.0 // valence (distance) for to faked per roundabout edge in front (inducing inner lane usage in roundabouts by decreasing sense of lc-urgency) 77 #define ROUNDABOUT_DIST_FACTOR (double)10.0 // Must be >=1.0, serves an alternative way of decreasing sense lc-urgency by multiplying the distance along the next roundabout 78 #define ROUNDABOUT_DIST_TRESH (double)10.0 // roundabout distances below ROUNDABOUT_DIST_TRESH are not multiplied by ROUNDABOUT_DIST_FACTOR 80 #define KEEP_RIGHT_HEADWAY (double)2.0 81 #define MAX_ONRAMP_LENGTH (double)200. 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 96 #define DEBUG_COND (myVehicle.isSelected()) 103 mySpeedGainProbability(0),
104 myKeepRightProbability(0),
105 myLeadingBlockerLength(0),
113 myChangeProbThresholdRight(2.0 * myKeepRightParam /
MAX2(
NUMERICAL_EPS, mySpeedGainParam)),
115 #ifdef DEBUG_CONSTRUCTOR 144 const std::pair<MSVehicle*, double>& leader,
145 const std::pair<MSVehicle*, double>& neighLead,
146 const std::pair<MSVehicle*, double>& neighFollow,
148 const std::vector<MSVehicle::LaneQ>& preb,
152 #ifdef DEBUG_WANTS_CHANGE 161 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
166 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
168 #ifdef DEBUG_WANTS_CHANGE 181 #ifdef DEBUG_PATCH_SPEED 183 std::cout <<
"\nPATCH_SPEED\n" 189 <<
" wanted=" << wanted <<
"\n";
193 const double newSpeed =
_patchSpeed(min, wanted, max, cfModel);
195 #ifdef DEBUG_PATCH_SPEED 197 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
210 #ifdef DEBUG_PATCH_SPEED 216 <<
" wanted=" << wanted << std::endl;
221 double MAGIC_offset = 1.;
225 #ifdef DEBUG_PATCH_SPEED 236 #ifdef DEBUG_PATCH_SPEED 238 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker, safe=" << safe << (safe +
NUMERICAL_EPS < min ?
" (not enough)" :
"") <<
"\n";
241 return MAX2(min, safe);
246 double nVSafe = wanted;
248 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
260 #ifdef DEBUG_PATCH_SPEED 262 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" got nVSafe=" << nVSafe <<
"\n";
267 #ifdef DEBUG_PATCH_SPEED 269 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
273 #ifdef DEBUG_PATCH_SPEED 275 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
283 #ifdef DEBUG_PATCH_SPEED 285 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" got vSafe\n";
296 #ifdef DEBUG_PATCH_SPEED 298 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_WANTS_LANECHANGE (strat, no vSafe)\n";
301 return (max + wanted) / (double) 2.0;
305 #ifdef DEBUG_PATCH_SPEED 307 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_BLOCKED_BY_LEADER (coop)\n";
311 return (
MAX2(0., min) + wanted) / (double) 2.0;
317 #ifdef DEBUG_PATCH_SPEED 319 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_BLOCKED_BY_FOLLOWER (coop)\n";
322 return (max + wanted) / (double) 2.0;
363 #ifdef DEBUG_PATCH_SPEED 365 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_AMBLOCKINGLEADER\n";
368 return (max + wanted) / (double) 2.0;
372 #ifdef DEBUG_PATCH_SPEED 374 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_AMBLOCKINGFOLLOWER_DONTBRAKE\n";
400 #ifdef DEBUG_INFORMED 404 <<
" informedBy=" << sender->
getID()
405 <<
" info=" << pinfo->second
406 <<
" vSafe=" << pinfo->first
418 double overtakeDist = (gap
423 return MAX2(overtakeDist, 0.);
431 const std::pair<MSVehicle*, double>& neighLead,
432 double remainingSeconds) {
435 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
438 plannedSpeed =
MIN2(plannedSpeed, v);
441 #ifdef DEBUG_INFORMER 443 std::cout <<
"\nINFORM_LEADER" 449 assert(neighLead.first != 0);
451 #ifdef DEBUG_INFORMER 453 std::cout <<
" blocked by leader nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 460 const double dv = plannedSpeed - nv->
getSpeed();
463 overtakeTime = overtakeDist / dv;
466 overtakeTime = remainingSeconds + 1;
469 #ifdef DEBUG_INFORMER 472 <<
"\nnv = " << nv->
getID()
473 <<
"\nplannedSpeed = " << plannedSpeed
474 <<
"\nleaderSpeed = " << nv->
getSpeed()
476 <<
"\nremainingSeconds = " << remainingSeconds
477 <<
"\novertakeDist = " << overtakeDist
478 <<
"\novertakeTime = " << overtakeTime
493 && !(
isOpposite() && neighLead.second < 0 && neighLead.first->isStopped())) {
505 #ifdef DEBUG_INFORMER 508 <<
" cannot overtake leader nv=" << nv->
getID()
512 <<
" overtakeDist=" << overtakeDist
513 <<
" overtakeTime=" << overtakeTime
514 <<
" remainingSeconds=" << remainingSeconds
515 <<
" currentGap=" << neighLead.second
518 <<
" targetSpeed=" << targetSpeed
519 <<
" nextSpeed=" << nextSpeed
527 #ifdef DEBUG_INFORMER 530 <<
" cannot overtake fast leader nv=" << nv->
getID()
534 <<
" overtakeDist=" << overtakeDist
536 <<
" overtakeTime=" << overtakeTime
537 <<
" remainingSeconds=" << remainingSeconds
538 <<
" currentGap=" << neighLead.second
539 <<
" targetSpeed=" << targetSpeed
548 #ifdef DEBUG_INFORMER 551 <<
" wants to overtake leader nv=" << nv->
getID()
553 <<
" overtakeDist=" << overtakeDist
554 <<
" remainingSeconds=" << remainingSeconds
555 <<
" overtakeTime=" << overtakeTime
556 <<
" currentGap=" << neighLead.second
564 }
else if (neighLead.first != 0) {
572 #ifdef DEBUG_INFORMER 574 std::cout <<
" not blocked by leader nv=" << nv->
getID()
576 <<
" gap=" << neighLead.second
577 <<
" nextGap=" << neighLead.second - dv
579 <<
" targetSpeed=" << targetSpeed
583 return MIN2(targetSpeed, plannedSpeed);
594 const std::pair<MSVehicle*, double>& neighFollow,
595 double remainingSeconds,
596 double plannedSpeed) {
601 #ifdef DEBUG_INFORMER 603 std::cout <<
"\nINFORM_FOLLOWER" 610 #ifdef DEBUG_INFORMER 612 std::cout <<
" blocked by follower nv=" << nv->
getID() <<
" nvSpeed=" << nv->
getSpeed() <<
" needGap=" 620 if ((neededGap - neighFollow.second) / remainingSeconds < (
MAX2(plannedSpeed, 0.) - nv->
getSpeed())) {
621 #ifdef DEBUG_INFORMER 623 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help." <<
"\nneededGap = " << neededGap <<
"\n";
643 double neighNewSpeed;
645 double neighNewSpeed1s;
655 dv = plannedSpeed - neighNewSpeed1s;
662 decelGap = neighFollow.second + dv;
669 neighNewSpeed1s = nv->
getSpeed() - helpDecel;
681 #ifdef DEBUG_INFORMER 685 <<
" plannedSpeed=" << plannedSpeed
686 <<
" threshold=" << onRampThreshold
687 <<
" neighNewSpeed=" << neighNewSpeed
688 <<
" neighNewSpeed1s=" << neighNewSpeed1s
690 <<
" gap=" << neighFollow.second
691 <<
" decelGap=" << decelGap
692 <<
" secureGap=" << secureGap
699 && neighNewSpeed1s < onRampThreshold) {
703 if (decelGap > 0 && decelGap >= secureGap) {
711 double vsafe, vsafe1;
720 assert(vsafe <= vsafe1);
731 #ifdef DEBUG_INFORMER 733 std::cout <<
"nextGap=" << nextGap <<
" (without help decel) \n";
741 MAX2(0., plannedSpeed),
749 nv->
getSpeed(), plannedAccel, -decel2,
760 MAX2(0., plannedSpeed),
763 assert(vsafe >= vsafe1);
765 #ifdef DEBUG_INFORMER 767 std::cout <<
"nextGap=" << nextGap
768 <<
" (with vsafe1 and help decel) \nvsafe1=" << vsafe1
769 <<
" vsafe=" << vsafe
778 if (nextGap < nextSecureGap) {
780 vsafe = neighNewSpeed;
783 #ifdef DEBUG_INFORMER 785 std::cout <<
"nextGap=" << nextGap
786 <<
" minNextSecureGap=" << nextSecureGap
787 <<
" vsafe=" << vsafe <<
"\n";
795 #ifdef DEBUG_INFORMER 797 std::cout <<
" wants to cut in before nv=" << nv->
getID()
798 <<
" vsafe1=" << vsafe1 <<
" vsafe=" << vsafe
824 #ifdef DEBUG_INFORMER 826 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
833 #ifdef DEBUG_INFORMER 835 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (nv cannot overtake right)\n";
854 #ifdef DEBUG_INFORMER 858 std::cout <<
" wants right follower to slow down a bit\n";
865 #ifdef DEBUG_INFORMER 868 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
890 if (gapAfterRemainingSecs >= secureGapAfterRemainingSecs) {
891 #ifdef DEBUG_INFORMER 893 std::cout <<
" wants to cut in before follower nv=" << nv->
getID() <<
" (eventually)\n";
906 #ifdef DEBUG_INFORMER 910 <<
" informs follower " << nv->
getID()
911 <<
" vhelp=" << vhelp
920 const double needDV = overtakeDist / remainingSeconds;
924 #ifdef DEBUG_INFORMER 928 <<
" wants to be overtaken by=" << nv->
getID()
929 <<
" overtakeDist=" << overtakeDist
931 <<
" vhelp=" << vhelp
932 <<
" needDV=" << needDV
941 double vsafe, vsafe1;
955 double anticipationTime = 1.;
966 if (anticipatedGap > secureGap) {
973 if (anticipatedGap < secureGap) {
984 #ifdef DEBUG_INFORMER 986 std::cout <<
" wants to cut in before non-blocking follower nv=" << nv->
getID() <<
"\n";
1030 const std::pair<MSVehicle*, double>& leader,
1031 const std::pair<MSVehicle*, double>& neighLead,
1032 const std::pair<MSVehicle*, double>& neighFollow,
1034 const std::vector<MSVehicle::LaneQ>& preb,
1037 assert(laneOffset == 1 || laneOffset == -1);
1041 int bestLaneOffset = 0;
1046 double currentDist = 0;
1047 double neighDist = 0;
1056 const int prebOffset = (checkOpposite ? 0 : laneOffset);
1057 for (
int p = 0; p < (int) preb.size(); ++p) {
1058 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
1059 assert(p + prebOffset < (
int)preb.size());
1061 neigh = preb[p + prebOffset];
1062 currentDist = curr.
length;
1063 neighDist = neigh.
length;
1064 bestLaneOffset = curr.bestLaneOffset;
1065 if (bestLaneOffset == 0 && preb[p + prebOffset].bestLaneOffset == 0) {
1066 #ifdef DEBUG_WANTS_CHANGE 1070 <<
" bestLaneOffsetOld=" << bestLaneOffset
1071 <<
" bestLaneOffsetNew=" << laneOffset
1075 bestLaneOffset = prebOffset;
1077 best = preb[p + bestLaneOffset];
1083 const bool right = (laneOffset == -1);
1085 neigh = preb[preb.size() - 1];
1088 bestLaneOffset = -1;
1090 neighDist = neigh.
length;
1091 currentDist = curr.
length;
1097 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
1103 if (lastBlocked != firstBlocked) {
1107 #ifdef DEBUG_WANTS_CHANGE 1116 <<
" leaderGap=" << leader.second
1118 <<
" neighLeadGap=" << neighLead.second
1120 <<
" neighFollowGap=" << neighFollow.second
1143 assert(memoryFactor > 0.);
1151 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped()) {
1156 + leader.first->getVehicleType().getLengthWithGap());
1157 }
else if (bestLaneOffset == laneOffset && neighLead.first != 0 && neighLead.first->isStopped()) {
1160 + neighLead.first->getVehicleType().getLengthWithGap();
1175 double roundaboutDistanceAhead = 0;
1176 double roundaboutDistanceAheadNeigh = 0;
1177 int roundaboutEdgesAhead = 0;
1178 int roundaboutEdgesAheadNeigh = 0;
1180 getRoundaboutAheadInfo(
this, curr, neigh, roundaboutDistanceAhead, roundaboutDistanceAheadNeigh, roundaboutEdgesAhead, roundaboutEdgesAheadNeigh);
1184 neighDist +=
roundaboutDistBonus(roundaboutDistanceAheadNeigh, roundaboutEdgesAheadNeigh);
1186 #ifdef DEBUG_WANTS_CHANGE 1188 if (roundaboutEdgesAhead > 0) {
1189 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
1197 const double maxJam =
MAX2(preb[currIdx + prebOffset].occupation, preb[currIdx].occupation);
1198 const double neighLeftPlace =
MAX2((
double) 0, neighDist - posOnLane - maxJam);
1200 #ifdef DEBUG_WANTS_CHANGE 1205 <<
" laDist=" << laDist
1206 <<
" currentDist=" << currentDist
1207 <<
" usableDist=" << usableDist
1208 <<
" bestLaneOffset=" << bestLaneOffset
1210 <<
" best.length=" << best.
length 1211 <<
" maxJam=" << maxJam
1212 <<
" neighLeftPlace=" << neighLeftPlace
1234 #ifdef DEBUG_WANTS_CHANGE 1237 <<
" avoid overtaking on the right nv=" << nv->
getID()
1240 <<
" plannedSpeed=" <<
myVSafes.back()
1254 #ifdef DEBUG_WANTS_CHANGE 1256 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
1260 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
1265 #ifdef DEBUG_WANTS_CHANGE 1267 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
1271 }
else if (bestLaneOffset == 0
1272 && (leader.first == 0 || !leader.first->isStopped())
1274 && roundaboutEdgesAhead == 0
1279 #ifdef DEBUG_WANTS_CHANGE 1281 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to leave the bestLane (neighDist=" << neighDist <<
")\n";
1288 #ifdef DEBUG_WANTS_CHANGE 1294 if ((ret & lcaCounter) != 0) {
1298 #ifdef DEBUG_WANTS_CHANGE 1300 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
1311 if (changeToBest &&
abs(bestLaneOffset) > 1) {
1314 #ifdef DEBUG_WANTS_CHANGE 1316 std::cout <<
" reserving space for unseen blockers myLeadingBlockerLength=" <<
myLeadingBlockerLength <<
"\n";
1324 if (*firstBlocked != neighLead.first) {
1328 const double remainingSeconds = ((ret &
LCA_TRACI) == 0 ?
1332 const double plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
1337 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
1340 #ifdef DEBUG_WANTS_CHANGE 1345 <<
" remainingSeconds=" << remainingSeconds
1346 <<
" plannedSpeed=" << plannedSpeed
1354 const double inconvenience =
MIN2((
double)1.0, (laneOffset < 0
1361 if (roundaboutEdgesAhead > 1) {
1363 #ifdef DEBUG_WANTS_CHANGE 1367 <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead
1397 #ifdef DEBUG_WANTS_CHANGE 1399 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
1419 && (!speedGainInconvenient)
1424 #ifdef DEBUG_WANTS_CHANGE 1428 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
1478 if (neighLead.first == 0) {
1483 &
myVehicle, correctedSpeed, neighLead.second, neighLead.first->
getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
1485 if (leader.first == 0) {
1490 &
myVehicle, correctedSpeed, leader.second, leader.first->
getSpeed(), leader.first->getCarFollowModel().getMaxDecel()));
1494 thisLaneVSafe =
MIN2(thisLaneVSafe, vMax);
1495 neighLaneVSafe =
MIN2(neighLaneVSafe, vMax);
1496 const double relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
1503 #ifdef DEBUG_WANTS_CHANGE 1507 <<
" currentDist=" << currentDist
1508 <<
" neighDist=" << neighDist
1518 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
1535 if (mySpeedGainProbability < 0 || relativeGain > 0) {
1544 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()));
1556 #ifdef DEBUG_WANTS_CHANGE 1561 <<
" neighDist=" << neighDist
1563 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
1565 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
1566 <<
" acceptanceTime=" << acceptanceTime
1567 <<
" fullSpeedGap=" << fullSpeedGap
1568 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
1569 <<
" dProb=" << deltaProb
1582 #ifdef DEBUG_WANTS_CHANGE 1588 <<
" thisLaneVSafe=" << thisLaneVSafe
1589 <<
" neighLaneVSafe=" << neighLaneVSafe
1590 <<
" relativeGain=" << relativeGain
1591 <<
" blocked=" << blocked
1605 if (thisLaneVSafe > neighLaneVSafe) {
1624 #ifdef DEBUG_WANTS_CHANGE 1630 <<
" thisLaneVSafe=" << thisLaneVSafe
1631 <<
" neighLaneVSafe=" << neighLaneVSafe
1632 <<
" relativeGain=" << relativeGain
1633 <<
" blocked=" << blocked
1647 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1654 #ifdef DEBUG_WANTS_CHANGE 1660 <<
" thisLaneVSafe=" << thisLaneVSafe
1661 <<
" neighLaneVSafe=" << neighLaneVSafe
1672 double& roundaboutDistanceAhead,
double& roundaboutDistanceAheadNeigh,
int& roundaboutEdgesAhead,
int& roundaboutEdgesAheadNeigh) {
1684 roundaboutDistanceAheadNeigh = 0;
1685 double neighPosition = pos;
1695 if (*i != 0 && *i != veh.
getLane()) {
1700 assert(nextLane != 0);
1709 #ifdef DEBUG_WANTS_CHANGE 1711 std::cout <<
"roundaboutDistanceAhead = " << roundaboutDistanceAhead
1712 <<
" roundaboutDistanceAheadNeigh = " << roundaboutDistanceAheadNeigh
1719 roundaboutEdgesAhead = 0;
1721 const MSLane* lane = *it;
1723 roundaboutEdgesAhead += 1;
1724 }
else if (roundaboutEdgesAhead > 0) {
1729 roundaboutEdgesAheadNeigh = 0;
1731 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
1732 roundaboutEdgesAheadNeigh += 1;
1733 }
else if (roundaboutEdgesAheadNeigh > 0) {
1750 if (roundaboutEdgesAhead > 1) {
1773 for (std::vector<MSLane*>::const_iterator i = continuationLanes.begin(); i != continuationLanes.end(); i++) {
1778 bool encounteredRoundabout =
false;
1779 double roundaboutDistanceAhead = 0.;
1782 std::vector<MSLane*>::const_iterator j = continuationLanes.begin();
1783 while (j != continuationLanes.end() && *j == 0) {
1788 if (j == continuationLanes.end()) {
1790 assert(initialLane == 0);
1792 }
else if (initialLane == 0) {
1797 }
else if (!initialLane->
isInternal() && initialLane != *j) {
1804 assert(position >= 0. && position <= initialLane->getLength());
1806 assert(initialLane == *j);
1807 roundaboutDistanceAhead += initialLane->
getLength() - position;
1808 if (j + 1 == continuationLanes.end() || *(j + 1) == 0 || !(*(j + 1))->getEdge().isRoundabout()) {
1812 const MSLane* nextLane = *(j + 1);
1820 roundaboutDistanceAhead += initialLane->
getLength() - position;
1822 roundaboutDistanceAhead += initialLane->
getLinkCont()[0]->getInternalLengthsAfter();
1827 for (std::vector<MSLane*>::const_iterator it = j; it != continuationLanes.end(); ++it) {
1828 const MSLane* lane = *it;
1831 encounteredRoundabout =
true;
1833 roundaboutDistanceAhead += lane->
getLength();
1838 if (it + 1 != continuationLanes.end() && *(it + 1) != 0 && (*(it + 1))->getEdge().isRoundabout()) {
1843 roundaboutDistanceAhead += linkLength;
1845 }
else if (encounteredRoundabout) {
1850 return roundaboutDistanceAhead;
1858 if ((*blocked) != 0) {
1860 #ifdef DEBUG_SLOW_DOWN 1884 (*blocked)->getCarFollowModel().getMaxDecel()));
1887 #ifdef DEBUG_SLOW_DOWN 1891 <<
" slowing down for" 1893 <<
" helpSpeed=" <<
myVSafes.back()
1913 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1929 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1941 #ifdef DEBUG_SAVE_BLOCKER_LENGTH 1947 <<
" potential=" << potential
double myLeadingBlockerLength
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 getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time, assuming that during...
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
MSLCM_LC2013(MSVehicle &v)
The action is due to the default of keeping right "Rechtsfahrgebot".
The action is done to help someone else.
double getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
#define LOOK_FORWARD_RIGHT
MSLane * getLane() const
Returns the lane the vehicle is on.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
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)
double myKeepRightProbability
#define KEEP_RIGHT_ACCEPTANCE
The car-following model abstraction.
double getPositionOnLane() const
Get the vehicle's position along the lane.
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
#define MAX_ONRAMP_LENGTH
int getBestLaneOffset() const
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)
helper function for doing the actual work
bool isRoundabout() const
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
double _patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
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 std::string & getID() const
Returns the id.
std::pair< double, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
double getInternalLengthsAfter() const
Returns the cumulative length of all internal lanes after this link.
double length
The overall length which may be driven when using this lane without a lane change.
The action is due to the wish to be faster (tactical lc)
#define UNUSED_PARAMETER(x)
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
const double myChangeProbThresholdRight
bool hasLaneChanger() const
#define ROUNDABOUT_DIST_FACTOR
MSAbstractLaneChangeModel & getLaneChangeModel()
static double distanceAlongNextRoundabout(double position, const MSLane *initialLane, const std::vector< MSLane *> &continuationLanes)
compute the distance on the next upcoming roundabout along a given sequence of lanes.
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation...
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Needs to stay on the current lane.
const LaneChangeModel myModel
the type of this model
#define ROUNDABOUT_DIST_BONUS
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
bool debugVehicle() const
whether the current vehicles shall be debugged
A class responsible for exchanging messages between cars involved in lane-change interaction.
static double overtakeDistance(const MSVehicle *follower, const MSVehicle *leader, const double gap, double followerSpeed=INVALID_SPEED, double leaderSpeed=INVALID_SPEED)
MSLane * lane
The described lane.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
A lane change model developed by D. Krajzewicz, J. Erdmann et al. between 2004 and 2013...
bool cancelRequest(int state)
whether the influencer cancels the given request
double mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial ...
void informFollower(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighFollow, double remainingSeconds, double plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
blocked in all directions
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
The action is urgent (to be defined by lc-model)
const double myChangeProbThresholdLeft
#define CUT_IN_LEFT_SPEED_THRESHOLD
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
#define LOOK_AHEAD_SPEED_MEMORY
const double myExperimentalParam1
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
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 method gets th...
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
#define RELGAIN_NORMALIZATION_MIN_SPEED
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'...
double getMinGap() const
Get the free space in front of vehicles of this class.
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.
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
std::vector< double > myVSafes
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...
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
Influencer & getInfluencer()
Returns the velocity/lane influencer.
LaneChangeAction
The state of a vehicle's lane-change behavior.
static void getRoundaboutAheadInfo(const MSLCM_LC2013 *lcm, const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, double &roundaboutDistanceAhead, double &roundaboutDistanceAheadNeigh, int &roundaboutEdgesAhead, int &roundaboutEdgesAheadNeigh)
computes the distance and number of edges in the next upcoming roundabout along the lane continuation...
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
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.
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key ...
static MSLink * getConnectingLink(const MSLane &from, const MSLane &to)
Returns the link connecting both lanes Both lanes have to be non-internal; 0 may be returned if no co...
std::vector< MSLane * > bestContinuations
static double _2double(const E *const data)
converts a char-type array into the double value described by it
double myCooperativeParam
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key ...
double getLength() const
Get vehicle's length [m].
virtual void prepareStep()
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
virtual void saveBlockerLength(double length)
reserve space at the end of the lane to avoid dead locks
#define LOOK_FORWARD_LEFT
The action is due to a TraCI request.
static bool gSemiImplicitEulerUpdate
bool amBlockingFollowerPlusNB()
#define ROUNDABOUT_DIST_TRESH
double informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, double > &neighLead, double remainingSeconds)
bool isStopped() const
Returns whether the vehicle is at a stop.
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)
#define LOOK_AHEAD_MIN_SPEED
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
#define LCA_RIGHT_IMPATIENCE
double getSpeed() const
Returns the vehicle's current speed.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
The edge is an internal edge.
void * inform(void *info, MSVehicle *sender)
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.
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) ...
bool isAccelLane() const
return whether this lane is an acceleration lane
#define HELP_DECEL_FACTOR
double roundaboutDistBonus(double roundaboutDistAhead, int roundaboutEdgesAhead) const
Computes the artificial bonus distance for roundabout lanes this additional distance reduces the sens...