42 #define OPPOSITE_OVERTAKING_SAFE_TIMEGAP 0.0 44 #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD 150.0 // just a guess 45 #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD_EMERGENCY 1000.0 // just a guess 47 #define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD 200.0 // just a guess 61 #define DEBUG_COND (vehicle->isSelected()) 75 aheadNext(lane, 0, 0) {
95 for (std::vector<MSLane*>::const_iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
97 myChanger.back().mayChangeRight = lane != lanes->begin();
98 myChanger.back().mayChangeLeft = (lane + 1) != lanes->end();
100 if ((*lane)->isInternal()) {
101 if (
myChanger.back().mayChangeRight && (*lane)->getLogicalPredecessorLane() == (*(lane - 1))->getLogicalPredecessorLane()) {
104 if (
myChanger.back().mayChangeLeft && (*lane)->getLogicalPredecessorLane() == (*(lane + 1))->getLogicalPredecessorLane()) {
125 const bool haveChanged =
change();
132 ce->lane->releaseVehicles();
146 ce->firstBlocked = 0;
148 ce->lane->getVehiclesSecure();
185 ce->lane->swapAfterLaneChange(t);
186 ce->lane->releaseVehicles();
196 #ifdef DEBUG_CANDIDATE 197 std::cout <<
SIMTIME <<
" findCandidate() on edge " <<
myChanger.begin()->lane->getEdge().getID() << std::endl;
204 #ifdef DEBUG_CANDIDATE 205 std::cout <<
" lane = " << ce->lane->getID() <<
"\n";
209 #ifdef DEBUG_CANDIDATE 215 assert(
veh(ce) != 0);
216 assert(
veh(max) != 0);
217 if (
veh(max)->getPositionOnLane() <
veh(ce)->getPositionOnLane()) {
218 #ifdef DEBUG_CANDIDATE 225 assert(
veh(max) != 0);
232 if (direction == 0) {
238 if (direction == -1) {
239 return myCandi->mayChangeRight && (
myCandi - 1)->lane->allowsVehicleClass(
veh(
myCandi)->getVehicleType().getVehicleClass());
240 }
else if (direction == 1) {
241 return myCandi->mayChangeLeft && (
myCandi + 1)->lane->allowsVehicleClass(
veh(
myCandi)->getVehicleType().getVehicleClass());
258 #ifdef DEBUG_ACTIONSTEPS 281 #ifdef DEBUG_ACTIONSTEPS 283 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' skips regular change checks." << std::endl;
286 bool changed =
false;
310 for (
int i = 0; i < (int)
myChanger.size(); ++i) {
314 const std::vector<MSVehicle::LaneQ>& preb = vehicle->
getBestLanes();
325 if ((stateRight & LCA_RIGHT) != 0 && (stateRight &
LCA_URGENT) != 0) {
326 (
myCandi - 1)->lastBlocked = vehicle;
327 if ((
myCandi - 1)->firstBlocked == 0) {
328 (
myCandi - 1)->firstBlocked = vehicle;
343 if ((stateLeft & LCA_LEFT) != 0 && (stateLeft &
LCA_URGENT) != 0) {
344 (
myCandi + 1)->lastBlocked = vehicle;
345 if ((
myCandi + 1)->firstBlocked == 0) {
346 (
myCandi + 1)->firstBlocked = vehicle;
389 <<
" veh=" << vehicle->
getID()
392 << ((newstate &
LCA_BLOCKED) != 0 ?
" (blocked)" :
"")
403 bool changed =
false;
405 const int dir = (state &
LCA_RIGHT) != 0 ? -1 : ((state &
LCA_LEFT) != 0 ? 1 : 0);
406 const bool execute = dir != 0 && ((state &
LCA_BLOCKED) == 0);
414 to->registerHop(vehicle);
432 to->registerHop(vehicle);
446 MSLane* target = to->lane;
449 to->registerHop(vehicle);
451 from->registerHop(vehicle);
461 shadow->hoppedVeh = vehicle;
465 #ifdef DEBUG_CONTINUE_CHANGE 468 <<
" continueChange veh=" << vehicle->
getID()
470 <<
" dir=" << direction
471 <<
" pastMidpoint=" << pastMidpoint
483 std::pair<MSVehicle* const, double>
487 #ifdef DEBUG_SURROUNDING_VEHICLES 489 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' looks for leader on lc-target lane '" << target->lane->getID() <<
"'." << std::endl;
495 #ifdef DEBUG_SURROUNDING_VEHICLES 497 if (neighLead != 0) {
498 std::cout <<
"Considering '" << neighLead->
getID() <<
"' at position " << neighLead->
getPositionOnLane() << std::endl;
509 if (target->hoppedVeh != 0) {
510 double hoppedPos = target->hoppedVeh->getPositionOnLane();
511 #ifdef DEBUG_SURROUNDING_VEHICLES 513 std::cout <<
"Considering hopped vehicle '" << target->hoppedVeh->getID() <<
"' at position " << hoppedPos << std::endl;
517 neighLead = target->hoppedVeh;
521 if (neighLead == 0) {
522 #ifdef DEBUG_SURROUNDING_VEHICLES 524 std::cout <<
"Looking for leader on consecutive lanes." << std::endl;
529 MSLane* targetLane = target->lane;
531 double leaderBack = targetLane->
getLength();
534 if (plBack < leaderBack &&
540 if (neighLead != 0) {
541 #ifdef DEBUG_SURROUNDING_VEHICLES 543 std::cout <<
" found leader=" << neighLead->
getID() <<
" (partial)\n";
552 if (seen > dist && !
myCandi->lane->isInternal()) {
553 #ifdef DEBUG_SURROUNDING_VEHICLES 555 std::cout <<
" found no leader within dist=" << dist <<
"\n";
558 return std::pair<MSVehicle* const, double>(
static_cast<MSVehicle*
>(0), -1);
562 std::pair<MSVehicle* const, double> result = target->lane->getLeaderOnConsecutive(dist, seen, speed, *
veh(
myCandi), bestLaneConts);
563 #ifdef DEBUG_SURROUNDING_VEHICLES 571 #ifdef DEBUG_SURROUNDING_VEHICLES 573 std::cout <<
" found leader=" << neighLead->
getID() <<
"\n";
581 std::pair<MSVehicle* const, double>
585 #ifdef DEBUG_SURROUNDING_VEHICLES 588 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' looks for follower on lc-target lane '" << target->lane->getID() <<
"'." << std::endl;
595 #ifdef DEBUG_SURROUNDING_VEHICLES 597 if (neighFollow != 0) {
598 std::cout <<
"veh(target) returns '" << neighFollow->
getID() <<
"' at position " << neighFollow->
getPositionOnLane() << std::endl;
600 std::cout <<
"veh(target) returns none." << std::endl;
606 #ifdef DEBUG_SURROUNDING_VEHICLES 608 if (
getCloserFollower(candiPos, neighFollow, target->hoppedVeh) != neighFollow) {
609 std::cout <<
"Hopped vehicle '" << target->hoppedVeh->getID() <<
"' at position " << target->hoppedVeh->getPositionOnLane() <<
" is closer." << std::endl;
618 #ifdef DEBUG_SURROUNDING_VEHICLES 621 if (partialBehind != 0 && partialBehind != neighFollow) {
622 std::cout <<
"'Partial behind'-vehicle '" << target->lane->getPartialBehind(candi)->
getID() <<
"' at position " << partialBehind->
getPositionOnLane() <<
" is closer." << std::endl;
627 neighFollow =
getCloserFollower(candiPos, neighFollow, target->lane->getPartialBehind(candi));
629 if (neighFollow == 0) {
631 #ifdef DEBUG_SURROUNDING_VEHICLES 633 if (consecutiveFollower.first == 0) {
634 std::cout <<
"no follower found." << std::endl;
636 std::cout <<
"found follower '" << consecutiveFollower.first->
getID() <<
"' on consecutive lanes." << std::endl;
640 return std::make_pair(const_cast<MSVehicle*>(consecutiveFollower.first), consecutiveFollower.second);
642 #ifdef DEBUG_SURROUNDING_VEHICLES 644 std::cout <<
"found follower '" << neighFollow->
getID() <<
"'." << std::endl;
648 return std::pair<MSVehicle* const, double>(neighFollow,
672 const std::pair<MSVehicle* const, double>& leader,
673 const std::vector<MSVehicle::LaneQ>& preb)
const {
677 if (neighLead.first != 0 && neighLead.first == neighFollow.first) {
680 neighFollow.first = 0;
683 return checkChange(laneOffset, target->lane, leader, neighLead, neighFollow, preb);
690 const std::pair<MSVehicle* const, double>& leader,
691 const std::pair<MSVehicle* const, double>& neighLead,
692 const std::pair<MSVehicle* const, double>& neighFollow,
693 const std::vector<MSVehicle::LaneQ>& preb)
const {
697 #ifdef DEBUG_CHECK_CHANGE 700 <<
"\n" <<
SIMTIME <<
" checkChange() for vehicle '" << vehicle->
getID() <<
"'" 709 if (neighFollow.first != 0 && neighFollow.second < 0) {
713 #ifdef DEBUG_CHECK_CHANGE 716 <<
" overlapping with follower..." 722 if (neighLead.first != 0 && neighLead.second < 0) {
725 #ifdef DEBUG_CHECK_CHANGE 728 <<
" overlapping with leader..." 739 if ((blocked & blockedByFollower) == 0 && neighFollow.first != 0) {
748 const double followerTauRemainder =
MAX2(neighFollow.first->getCarFollowModel().getHeadwayTime() -
TS, 0.);
749 const double vNextFollower = neighFollow.first->getSpeed() +
MAX2(0., followerTauRemainder * neighFollow.first->getAcceleration());
752 secureBackGap = neighFollow.first->getCarFollowModel().getSecureGap(vNextFollower,
755 blocked |= blockedByFollower;
758 #ifdef DEBUG_CHECK_CHANGE 761 <<
" back gap unsafe: " 762 <<
"gap = " << neighFollow.second
764 << neighFollow.first->getCarFollowModel().getSecureGap(vNextFollower,
774 if ((blocked & blockedByLeader) == 0 && neighLead.first != 0) {
785 const double vNextLeader = neighLead.first->getSpeed() +
MIN2(0., followerTauRemainder * neighLead.first->getAcceleration());
788 vNextLeader, neighLead.first->getCarFollowModel().getMaxDecel());
790 blocked |= blockedByLeader;
793 #ifdef DEBUG_CHECK_CHANGE 796 <<
" front gap unsafe: " 797 <<
"gap = " << neighLead.second
800 vNextLeader, neighLead.first->getCarFollowModel().getMaxDecel())
811 if (leader.first != 0) {
815 #ifdef DEBUG_CHECK_CHANGE 817 std::cout <<
SIMTIME <<
" pedestrian on road " + leader.first->getID() <<
" gap=" << gap <<
" brakeGap=" << brakeGap <<
"\n";
820 if (brakeGap > gap) {
821 blocked |= blockedByLeader;
822 #ifdef DEBUG_CHECK_CHANGE 824 std::cout <<
SIMTIME <<
" blocked by pedestrian " + leader.first->getID() <<
"\n";
831 if (leader.first != 0) {
837 laneOffset, msg, blocked, leader, neighLead, neighFollow, *targetLane, preb, &(
myCandi->lastBlocked), &(
myCandi->firstBlocked));
846 const double speed = vehicle->
getSpeed();
848 if (seen < dist || myCandi->lane->isInternal()) {
849 std::pair<MSVehicle* const, double> neighLead2 = targetLane->
getCriticalLeader(dist, seen, speed, *vehicle);
850 if (neighLead2.first != 0 && neighLead2.first != neighLead.first) {
852 neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel());
854 #ifdef DEBUG_SURROUNDING_VEHICLES 856 std::cout <<
SIMTIME <<
" found critical leader=" << neighLead2.first->getID()
857 <<
" gap=" << neighLead2.second <<
" secGap=" << secureGap <<
" secGap2=" << secureGap2 <<
"\n";
860 if (neighLead2.second < secureGap2) {
861 state |= blockedByLeader;
866 if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
869 state |= blockedByLeader;
881 if (estimatedLCDuration == -1) {
883 #ifdef DEBUG_CHECK_CHANGE 885 std::cout <<
SIMTIME <<
" checkChange() too slow to guarantee completion of continuous lane change." 886 <<
"\nestimatedLCDuration=" << estimatedLCDuration
887 <<
"\ndistToNeighLane=" << distToNeighLane
895 const double avgSpeed = 0.5 * (
899 const double space2change = avgSpeed * estimatedLCDuration;
902 #ifdef DEBUG_CHECK_CHANGE 904 std::cout <<
SIMTIME <<
" checkChange() checking continuous lane change..." 905 <<
"\ndistToNeighLane=" << distToNeighLane
906 <<
" estimatedLCDuration=" << estimatedLCDuration
907 <<
" space2change=" << space2change
908 <<
" avgSpeed=" << avgSpeed
917 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
918 while (!nextLane->
isLinkEnd(link) && seen <= space2change) {
922 || (nextLane->
getEdge().
isInternal() && (*link)->getViaLaneOrLane()->getEdge().isInternal())
927 if ((*link)->getViaLane() == 0) {
930 nextLane = (*link)->getViaLaneOrLane();
935 #ifdef DEBUG_CHECK_CHANGE 937 std::cout <<
" available distance=" << seen << std::endl;
940 if (nextLane->
isLinkEnd(link) && seen < space2change) {
941 #ifdef DEBUG_CHECK_CHANGE 943 std::cout <<
SIMTIME <<
" checkChange insufficientSpace: seen=" << seen <<
" space2change=" << space2change <<
"\n";
949 if ((state & LCA_BLOCKED) == 0) {
952 const double speed = vehicle->
getSpeed();
957 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
958 while (!nextLane->
isLinkEnd(link) && seen <= space2change && seen <= dist) {
959 nextLane = (*link)->getViaLaneOrLane();
961 if (targetLane == 0) {
965 std::pair<MSVehicle* const, double> neighLead2 = targetLane->
getLeader(vehicle, -seen, std::vector<MSLane*>());
966 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
968 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
969 state |= blockedByLeader;
973 if ((*link)->getViaLane() == 0) {
983 const int oldstate = state;
986 #ifdef DEBUG_CHECK_CHANGE 989 <<
" veh=" << vehicle->
getID()
998 if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
1023 bool oppositeChangeByTraci =
false;
1026 oppositeChangeByTraci =
true;
1029 if (!isOpposite && leader.first == 0 && !oppositeChangeByTraci) {
1037 if (opposite == 0) {
1041 int direction = isOpposite ? -1 : 1;
1042 std::pair<MSVehicle*, double> neighLead((
MSVehicle*)0, -1);
1045 double timeToOvertake;
1046 double spaceToOvertake;
1047 if (!isOpposite && !oppositeChangeByTraci) {
1048 assert(leader.first != 0);
1052 std::pair<MSVehicle*, double> columnLeader = leader;
1053 double egoGap = leader.second;
1054 bool foundSpaceAhead =
false;
1055 double seen = leader.second + leader.first->getVehicleType().getLengthWithGap();
1057 while (!foundSpaceAhead) {
1058 const double requiredSpaceAfterLeader = (columnLeader.first->getCarFollowModel().getSecureGap(
1064 const bool checkTmpVehicles = (&columnLeader.first->getLane()->getEdge() == &source->
getEdge());
1065 std::pair<MSVehicle* const, double> leadLead = columnLeader.first->getLane()->getLeader(
1066 columnLeader.first, columnLeader.first->getPositionOnLane(), conts, requiredSpaceAfterLeader + mergeBrakeGap,
1069 #ifdef DEBUG_CHANGE_OPPOSITE 1071 std::cout <<
" leadLead=" <<
Named::getIDSecure(leadLead.first) <<
" gap=" << leadLead.second <<
"\n";
1074 if (leadLead.first == 0) {
1075 foundSpaceAhead =
true;
1080 const double requiredSpace = (requiredSpaceAfterLeader
1081 + vehicle->
getCarFollowModel().
getSecureGap(overtakingSpeed, leadLead.first->getSpeed(), leadLead.first->getCarFollowModel().getMaxDecel()));
1082 if (leadLead.second > requiredSpace) {
1083 foundSpaceAhead =
true;
1085 #ifdef DEBUG_CHANGE_OPPOSITE 1087 std::cout <<
" not enough space after columnLeader=" << columnLeader.first->getID() <<
" required=" << requiredSpace <<
"\n";
1090 seen +=
MAX2(0., leadLead.second) + leadLead.first->getVehicleType().getLengthWithGap();
1091 if (seen > maxLookAhead) {
1092 #ifdef DEBUG_CHANGE_OPPOSITE 1094 std::cout <<
" cannot changeOpposite due to insufficient free space after columnLeader (seen=" << seen <<
" columnLeader=" << columnLeader.first->getID() <<
")\n";
1100 egoGap += columnLeader.first->getVehicleType().getLengthWithGap() + leadLead.second;
1101 columnLeader = leadLead;
1102 #ifdef DEBUG_CHANGE_OPPOSITE 1104 std::cout <<
" new columnLeader=" << columnLeader.first->getID() <<
"\n";
1110 #ifdef DEBUG_CHANGE_OPPOSITE 1112 std::cout <<
" compute time/space to overtake for columnLeader=" << columnLeader.first->getID() <<
" gap=" << columnLeader.second <<
"\n";
1118 #ifdef DEBUG_CHANGE_OPPOSITE 1120 std::cout <<
" cannot changeOpposite due to upcoming stop (dist=" << vehicle->
nextStopDist() <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
1127 #ifdef DEBUG_CHANGE_OPPOSITE 1130 <<
" veh=" << vehicle->
getID()
1131 <<
" changeOpposite opposite=" << opposite->
getID()
1133 <<
" timeToOvertake=" << timeToOvertake
1134 <<
" spaceToOvertake=" << spaceToOvertake
1139 if (neighLead.first != 0) {
1140 const MSVehicle* oncoming = neighLead.first;
1142 #ifdef DEBUG_CHANGE_OPPOSITE 1145 <<
" oncoming=" << oncoming->
getID()
1146 <<
" oncomingGap=" << neighLead.second
1147 <<
" leaderGap=" << leader.second
1151 if (neighLead.second - spaceToOvertake - timeToOvertake * oncoming->
getSpeed() < 0) {
1153 #ifdef DEBUG_CHANGE_OPPOSITE 1155 std::cout <<
" cannot changeOpposite due to dangerous oncoming\n";
1161 }
else if (!oppositeChangeByTraci) {
1162 timeToOvertake = -1;
1164 spaceToOvertake = std::numeric_limits<double>::max();
1176 if (usableDist < spaceToOvertake) {
1179 assert(bestLaneConts.size() >= 1);
1180 std::vector<MSLane*>::const_iterator it = bestLaneConts.begin() + 1;
1181 while (usableDist < spaceToOvertake && it != bestLaneConts.end()) {
1182 #ifdef DEBUG_CHANGE_OPPOSITE 1184 std::cout <<
" usableDist=" << usableDist <<
" opposite=" <<
Named::getIDSecure((*it)->getOpposite()) <<
"\n";
1187 if ((*it)->getOpposite() == 0) {
1192 if (*(it - 1) != 0) {
1201 #ifdef DEBUG_CHANGE_OPPOSITE 1203 std::cout <<
" stop lookahead at link=" << (link == 0 ?
"NULL" : link->
getViaLaneOrLane()->
getID()) <<
" state=" << (link == 0 ?
"?" :
toString(link->getState())) <<
" ignoreRed=" << vehicle->
ignoreRed(link,
true) <<
"\n";
1209 usableDist += (*it)->getLength();
1213 if (!isOpposite && usableDist < spaceToOvertake) {
1214 #ifdef DEBUG_CHANGE_OPPOSITE 1216 std::cout <<
" cannot changeOpposite due to insufficient space (seen=" << usableDist <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
1221 #ifdef DEBUG_CHANGE_OPPOSITE 1223 std::cout <<
" usableDist=" << usableDist <<
" spaceToOvertake=" << spaceToOvertake <<
" timeToOvertake=" << timeToOvertake <<
"\n";
1228 std::vector<MSVehicle::LaneQ> preb = vehicle->
getBestLanes();
1243 if (leader.first != 0) {
1245 #ifdef DEBUG_CHANGE_OPPOSITE 1247 std::cout <<
SIMTIME <<
" found oncoming leader=" << leader.first->getID() <<
" gap=" << leader.second <<
"\n";
1252 #ifdef DEBUG_CHANGE_OPPOSITE 1254 std::cout <<
SIMTIME <<
" veh=" << vehicle->
getID() <<
" remaining dist=" << laneQ.
length - forwardPos <<
" forwardPos=" << forwardPos <<
" laneQ.length=" << laneQ.
length <<
"\n";
1259 int state =
checkChange(direction, opposite, leader, neighLead, neighFollow, preb);
1261 bool changingAllowed = (state &
LCA_BLOCKED) == 0;
1274 #ifdef DEBUG_CHANGE_OPPOSITE 1276 std::cout <<
SIMTIME <<
" changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction <<
" opposite=" <<
Named::getIDSecure(opposite) <<
" state=" << state <<
"\n";
1281 #ifdef DEBUG_CHANGE_OPPOSITE 1283 std::cout <<
SIMTIME <<
" not changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction
1301 const double v = vehicle->
getSpeed();
1302 const double u = leader->
getSpeed();
1314 const double sign = -1;
1318 double t = (u - v - sqrt(4 * (u - v) * (u - v) + 8 * a * g) * sign * 0.5) / a;
1323 t = ceil(t /
TS) *
TS;
1326 const double timeToMaxSpeed = (vMax - v) / a;
1328 if (t <= timeToMaxSpeed) {
1330 spaceToOvertake = v * t + t * t * a * 0.5;
1334 const double s = v * timeToMaxSpeed + timeToMaxSpeed * timeToMaxSpeed * a * 0.5;
1335 const double m = timeToMaxSpeed;
1338 t = (g - s + m * vMax) / (vMax - u);
1343 t = ceil(t /
TS) *
TS;
1346 spaceToOvertake = s + (t - m) * vMax;
double myPos
the stored position
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double computeAngle() const
compute the current vehicle angle
static MSVehicle * getCloserFollower(const double maxPos, MSVehicle *follow1, MSVehicle *follow2)
return the closer follower of ego
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 tau (i...
bool ignoreRed(const MSLink *link, bool canBrake) const
decide whether a red (or yellow light) may be ignore
MSEdge & getEdge() const
Returns the lane's edge.
double myAngle
the angle in radians (
Representation of a vehicle in the micro simulation.
bool isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
MSLane * lane
the lane corresponding to this ChangeElem (the current change candidate is on this lane) ...
The action is done to help someone else.
LinkDirection getDirection() const
Returns the direction the vehicle passing this link take.
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
State myState
This Vehicles driving state (pos and speed)
virtual double getAssumedDecelForLaneChangeDuration() const
Returns a deceleration value which is used for the estimation of the duration of a lane change...
MSLane * getLane() const
Returns the lane the vehicle is on.
void setLeaderGaps(CLeaderDist, double secGap)
The vehicle is blocked by left follower.
int checkChange(int laneOffset, const MSLane *targetLane, const std::pair< MSVehicle *const, double > &leader, const std::pair< MSVehicle *const, double > &neighLead, const std::pair< MSVehicle *const, double > &neighFollow, const std::vector< MSVehicle::LaneQ > &preb) const
bool continueChange(MSVehicle *vehicle, ChangerIt &from)
continue a lane change maneuver and return whether the midpoint was passed in this step (used if gLan...
virtual void initChanger()
Initialize the changer before looping over all vehicles.
int getShadowDirection() const
return the direction in which the current shadow lane lies
virtual bool changeOpposite(std::pair< MSVehicle *, double > leader)
const bool myAllowsChanging
double getPositionOnLane() const
Get the vehicle's position along the lane.
double myPosLat
the stored lateral position
MSVehicle * veh(ConstChangerIt ce) const
std::pair< MSVehicle *const, double > getRealLeader(const ChangerIt &target) const
Vehicle is too slow to guarantee success of lane change (used for continuous lane changing in case th...
const bool myChangeToOpposite
whether this edge allows changing to the opposite direction edge
#define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD
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
bool isLinkEnd(MSLinkCont::const_iterator &i) const
bool isStoppedOnLane() const
double getRightSideOnLane() const
Get the vehicle's lateral position on the lane:
void adaptBestLanesOccupation(int laneIndex, double density)
update occupation from MSLaneChanger
bool alreadyChanged() const
reset the flag whether a vehicle already moved to false
static const double NO_NEIGHBOR
void startChange(MSVehicle *vehicle, ChangerIt &from, int direction)
start the lane change maneuver (and finish it instantly if gLaneChangeDuration == 0) ...
const std::string & getID() const
Returns the id.
ChangeElem(MSLane *_lane)
double length
The overall length which may be driven when using this lane without a lane change.
VehCont myPartialVehicles
The lane's partial vehicles. This container holds all vehicles that are partially on this lane but wh...
double getWidth() const
Returns the lane's width.
ChangerIt findCandidate()
Find current candidate. If there is none, myChanger.end() is returned.
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
void checkTraCICommands()
Check for commands issued for the vehicle via TraCI and apply the appropriate state changes For the s...
MSAbstractLaneChangeModel & getLaneChangeModel()
SUMOTime getLaneTimeLineDuration()
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
bool vehInChanger() const
Check if there is a single change-candidate in the changer. Returns true if there is one...
LinkState getState() const
Returns the current state of the link.
bool applyTraCICommands(MSVehicle *vehicle)
Execute TraCI LC-commands.
The link is a straight direction.
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
void setFollowerGaps(CLeaderDist follower, double secGap)
void checkTraCICommands(MSVehicle *vehicle)
Take into account traci LC-commands.
A class responsible for exchanging messages between cars involved in lane-change interaction.
The vehicle changes lanes (micro only)
virtual double estimateLCDuration(const double speed, const double remainingManeuverDist, const double decel) const
Calculates the maximal time needed to complete a lane change maneuver if lcMaxSpeedLatFactor and lcMa...
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
virtual void updateChanger(bool vehHasChanged)
VehCont myTmpVehicles
Container for lane-changing vehicles. After completion of lane-change- process, the containers will b...
blocked in all directions
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
The action is urgent (to be defined by lc-model)
static MSPModel * getModel()
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
#define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD_EMERGENCY
virtual 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...
Position myCachedPosition
std::pair< MSVehicle *const, double > getOppositeFollower(const MSVehicle *ego) const
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
void registerHop(MSVehicle *vehicle)
Register that vehicle belongs to Changer Item to after LC decisions.
bool havePriority() const
Returns whether this link is a major link.
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
The link is a (hard) right direction.
std::pair< MSVehicle *const, double > getLeader(const MSVehicle *veh, const double vehPos, const std::vector< MSLane *> &bestLaneConts, double dist=-1, bool checkTmpVehicles=false) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
static void computeOvertakingTime(const MSVehicle *vehicle, const MSVehicle *leader, double gap, double &timeToOvertake, double &spaceToOvertake)
Compute the time and space required for overtaking the given leader.
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
double getMinGap() const
Get the free space in front of vehicles of this class.
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
MSLaneChanger()
Default constructor.
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
bool isInternal() const
return whether this edge is an internal edge
void updateLanes(SUMOTime t)
std::vector< MSVehicle * > VehCont
Container for vehicles.
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane *> &conts)
int checkChangeWithinEdge(int laneOffset, const std::pair< MSVehicle *const, double > &leader, const std::vector< MSVehicle::LaneQ > &preb) const
std::pair< MSVehicle *const, double > getRealFollower(const ChangerIt &target) const
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
void setOrigLeaderGaps(CLeaderDist, double secGap)
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
#define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD
std::pair< const MSPerson *, double > PersonDist
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
#define OPPOSITE_OVERTAKING_SAFE_TIMEGAP
std::pair< const MSVehicle *, double > CLeaderDist
Influencer & getInfluencer()
Returns the velocity/lane influencer.
virtual double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
LaneChangeAction
The state of a vehicle's lane-change behavior.
virtual void setOwnState(const int state)
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
bool isActive() const
Returns whether the current simulation step is an action point for the vehicle.
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...
virtual ~MSLaneChanger()
Destructor.
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
The vehicle is blocked being overlapping.
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
std::pair< MSVehicle *const, double > getCriticalLeader(double dist, double seen, double speed, const MSVehicle &veh) const
Returns the most dangerous leader and the distance to him.
double getLength() const
Get vehicle's length [m].
Changer myChanger
Container for ChangeElemements, one for every lane in the edge.
The action is due to a TraCI request.
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
void registerUnchanged(MSVehicle *vehicle)
The vehicle does not have enough space to complete a continuous lane and change before the next turni...
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
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)
MSVehicle * hoppedVeh
last vehicle that changed into this lane
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
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
public emergency vehicles
static SUMOTime gLaneChangeDuration
const std::string & getID() const
Returns the name of the vehicle.
Representation of a lane in the micro simulation.
double myBackPos
the stored back position
The vehicle is blocked by right follower.
bool mayChange(int direction) const
whether changing to the lane in the given direction should be considered
void saveLCState(const int dir, const int stateWithoutTraCI, const int state)
double getSpeedLat() const
return the lateral speed of the current lane change maneuver
bool haveRed() const
Returns whether this link is blocked by a red (or redyellow) traffic light.
Interface for lane-change models.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
static const Position INVALID
used to indicate that a position is valid
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)