48 #define OPPOSITE_OVERTAKING_SAFE_TIMEGAP 0.0 50 #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD 150.0 // just a guess 51 #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD_EMERGENCY 1000.0 // just a guess 53 #define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD 200.0 // just a guess 65 #define DEBUG_COND false 90 for (std::vector<MSLane*>::const_iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
109 const bool haveChanged =
change();
116 ce->lane->releaseVehicles();
130 ce->firstBlocked = 0;
132 ce->lane->getVehiclesSecure();
169 ce->lane->swapAfterLaneChange(t);
170 ce->lane->releaseVehicles();
189 assert(
veh(ce) != 0);
190 assert(
veh(max) != 0);
191 if (
veh(max)->getPositionOnLane() <
veh(ce)->getPositionOnLane()) {
197 assert(
veh(max) != 0);
204 if (direction == 0) {
210 if (direction == -1) {
212 }
else if (direction == 1) {
232 #ifdef DEBUG_VEHICLE_GUI_SELECTION 260 for (
int i = 0; i < (int)
myChanger.size(); ++i) {
263 const std::vector<MSVehicle::LaneQ>& preb = vehicle->
getBestLanes();
274 if ((stateRight & LCA_RIGHT) != 0 && (stateRight &
LCA_URGENT) != 0) {
275 (
myCandi - 1)->lastBlocked = vehicle;
276 if ((
myCandi - 1)->firstBlocked == 0) {
277 (
myCandi - 1)->firstBlocked = vehicle;
292 if ((stateLeft & LCA_LEFT) != 0 && (stateLeft &
LCA_URGENT) != 0) {
293 (
myCandi + 1)->lastBlocked = vehicle;
294 if ((
myCandi + 1)->firstBlocked == 0) {
295 (
myCandi + 1)->firstBlocked = vehicle;
336 to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
338 to->hoppedVeh = vehicle;
353 MSLane* target = to->lane;
356 to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
358 to->hoppedVeh = vehicle;
360 from->lane->myTmpVehicles.insert(from->lane->myTmpVehicles.begin(), vehicle);
362 from->hoppedVeh = vehicle;
372 shadow->hoppedVeh = vehicle;
376 #ifdef DEBUG_CONTINUE_CHANGE 379 <<
" continueChange veh=" << vehicle->
getID()
381 <<
" dir=" << direction
382 <<
" pastMidpoint=" << pastMidpoint
394 std::pair<MSVehicle* const, double>
398 #ifdef DEBUG_SURROUNDING_VEHICLES 401 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' looks for leader on lc-target lane '" << target->lane->getID() <<
"'." << std::endl;
407 #ifdef DEBUG_SURROUNDING_VEHICLES 409 if (neighLead != 0) {
410 std::cout <<
"Considering '" << neighLead->
getID() <<
"' at position " << neighLead->
getPositionOnLane() << std::endl;
421 if (target->hoppedVeh != 0) {
422 double hoppedPos = target->hoppedVeh->getPositionOnLane();
423 #ifdef DEBUG_SURROUNDING_VEHICLES 425 std::cout <<
"Considering hopped vehicle '" << target->hoppedVeh->getID() <<
"' at position " << hoppedPos << std::endl;
429 neighLead = target->hoppedVeh;
433 if (neighLead == 0) {
434 #ifdef DEBUG_SURROUNDING_VEHICLES 436 std::cout <<
"Looking for leader on consecutive lanes." << std::endl;
440 MSLane* targetLane = target->lane;
443 std::vector<MSVehicle*>::const_iterator i = targetLane->
myPartialVehicles.begin();
458 return std::pair<MSVehicle* const, double>(
static_cast<MSVehicle*
>(0), -1);
461 return target->lane->getLeaderOnConsecutive(dist, seen, speed, *
veh(
myCandi), bestLaneConts);
469 std::pair<MSVehicle* const, double>
473 #ifdef DEBUG_SURROUNDING_VEHICLES 476 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' looks for follower on lc-target lane '" << target->lane->getID() <<
"'." << std::endl;
483 #ifdef DEBUG_SURROUNDING_VEHICLES 485 if (neighFollow != 0) {
486 std::cout <<
"veh(target) returns '" << neighFollow->
getID() <<
"' at position " << neighFollow->
getPositionOnLane() << std::endl;
488 std::cout <<
"veh(target) returns none." << std::endl;
494 #ifdef DEBUG_SURROUNDING_VEHICLES 496 if (
getCloserFollower(candiPos, neighFollow, target->hoppedVeh) != neighFollow) {
497 std::cout <<
"Hopped vehicle '" << target->hoppedVeh->getID() <<
"' at position " << target->hoppedVeh->getPositionOnLane() <<
" is closer." << std::endl;
506 #ifdef DEBUG_SURROUNDING_VEHICLES 509 if (partialBehind != 0 && partialBehind != neighFollow) {
510 std::cout <<
"'Partial behind'-vehicle '" << target->lane->getPartialBehind(candi)->
getID() <<
"' at position " << target->hoppedVeh->getPositionOnLane() <<
" is closer." << std::endl;
515 neighFollow =
getCloserFollower(candiPos, neighFollow, target->lane->getPartialBehind(candi));
517 if (neighFollow == 0) {
519 #ifdef DEBUG_SURROUNDING_VEHICLES 521 if (consecutiveFollower.first == 0) {
522 std::cout <<
"no follower found." << std::endl;
524 std::cout <<
"found follower '" << consecutiveFollower.first->
getID() <<
"' on consecutive lanes." << std::endl;
528 return std::make_pair(const_cast<MSVehicle*>(consecutiveFollower.first), consecutiveFollower.second);
530 #ifdef DEBUG_SURROUNDING_VEHICLES 532 std::cout <<
"found follower '" << neighFollow->
getID() <<
"'." << std::endl;
536 return std::pair<MSVehicle* const, double>(neighFollow,
560 const std::pair<MSVehicle* const, double>& leader,
561 const std::vector<MSVehicle::LaneQ>& preb)
const {
565 if (neighLead.first != 0 && neighLead.first == neighFollow.first) {
568 neighFollow.first = 0;
571 return checkChange(laneOffset, target->lane, leader, neighLead, neighFollow, preb);
578 const std::pair<MSVehicle* const, double>& leader,
579 const std::pair<MSVehicle* const, double>& neighLead,
580 const std::pair<MSVehicle* const, double>& neighFollow,
581 const std::vector<MSVehicle::LaneQ>& preb)
const {
586 #ifdef DEBUG_CHECK_CHANGE 589 <<
"\n" <<
SIMTIME <<
" checkChange() for vehicle '" << vehicle->
getID() <<
"'" 599 if (neighFollow.first != 0 && neighFollow.second < 0) {
603 #ifdef DEBUG_CHECK_CHANGE 606 <<
" overlapping with follower..." 612 if (neighLead.first != 0 && neighLead.second < 0) {
616 #ifdef DEBUG_CHECK_CHANGE 619 <<
" overlapping with leader..." 629 if ((blocked & blockedByFollower) == 0 && neighFollow.first != 0) {
632 if (neighFollow.second < secureBackGap) {
633 blocked |= blockedByFollower;
636 #ifdef DEBUG_CHECK_CHANGE 639 <<
" back gap unsafe: " 640 <<
"gap = " << neighFollow.second
642 << neighFollow.first->getCarFollowModel().getSecureGap(neighFollow.first->getSpeed(),
652 if ((blocked & blockedByLeader) == 0 && neighLead.first != 0) {
655 if (neighLead.second < secureFrontGap) {
656 blocked |= blockedByLeader;
659 #ifdef DEBUG_CHECK_CHANGE 662 <<
" front gap unsafe: " 663 <<
"gap = " << neighLead.second
666 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())
677 laneOffset, msg, blocked, leader, neighLead, neighFollow, *targetLane, preb, &(
myCandi->lastBlocked), &(
myCandi->firstBlocked));
683 const double speed = vehicle->
getSpeed();
686 std::pair<MSVehicle* const, double> neighLead2 = targetLane->
getCriticalLeader(dist, seen, speed, *vehicle);
687 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
689 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
690 state |= blockedByLeader;
694 if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
697 state |= blockedByLeader;
706 const double avgSpeed = 0.5 * (
714 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
715 while (!nextLane->
isLinkEnd(link) && seen <= space2change) {
719 || (nextLane->
getEdge().
isInternal() && (*link)->getViaLaneOrLane()->getEdge().isInternal())
724 if ((*link)->getViaLane() == 0) {
727 nextLane = (*link)->getViaLaneOrLane();
732 if (nextLane->
isLinkEnd(link) && seen < space2change) {
733 #ifdef DEBUG_CHECK_CHANGE 735 std::cout <<
SIMTIME <<
" checkChange insufficientSpace: seen=" << seen <<
" space2change=" << space2change <<
"\n";
741 if ((state & LCA_BLOCKED) == 0) {
744 const double speed = vehicle->
getSpeed();
749 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
750 while (!nextLane->
isLinkEnd(link) && seen <= space2change && seen <= dist) {
751 nextLane = (*link)->getViaLaneOrLane();
753 if (targetLane == 0) {
757 std::pair<MSVehicle* const, double> neighLead2 = targetLane->
getLeader(vehicle, -seen, std::vector<MSLane*>());
758 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
760 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
761 state |= blockedByLeader;
765 if ((*link)->getViaLane() == 0) {
774 const int oldstate = state;
779 #ifdef DEBUG_CHECK_CHANGE 782 <<
" veh=" << vehicle->
getID()
791 if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
814 if (!isOpposite && leader.first == 0) {
826 int direction = isOpposite ? -1 : 1;
827 std::pair<MSVehicle*, double> neighLead((
MSVehicle*)0, -1);
830 double timeToOvertake;
831 double spaceToOvertake;
833 assert(leader.first != 0);
837 std::pair<MSVehicle*, double> columnLeader = leader;
838 double egoGap = leader.second;
839 bool foundSpaceAhead =
false;
840 double seen = leader.second + leader.first->getVehicleType().getLengthWithGap();
842 while (!foundSpaceAhead) {
843 const double requiredSpaceAfterLeader = (columnLeader.first->getCarFollowModel().getSecureGap(
849 const bool checkTmpVehicles = (&columnLeader.first->getLane()->getEdge() == &source->
getEdge());
850 std::pair<MSVehicle* const, double> leadLead = columnLeader.first->getLane()->getLeader(
851 columnLeader.first, columnLeader.first->getPositionOnLane(), conts, requiredSpaceAfterLeader + mergeBrakeGap,
854 #ifdef DEBUG_CHANGE_OPPOSITE 856 std::cout <<
" leadLead=" <<
Named::getIDSecure(leadLead.first) <<
" gap=" << leadLead.second <<
"\n";
859 if (leadLead.first == 0) {
860 foundSpaceAhead =
true;
865 const double requiredSpace = (requiredSpaceAfterLeader
866 + vehicle->
getCarFollowModel().
getSecureGap(overtakingSpeed, leadLead.first->getSpeed(), leadLead.first->getCarFollowModel().getMaxDecel()));
867 if (leadLead.second > requiredSpace) {
868 foundSpaceAhead =
true;
870 #ifdef DEBUG_CHANGE_OPPOSITE 872 std::cout <<
" not enough space after columnLeader=" << columnLeader.first->getID() <<
" required=" << requiredSpace <<
"\n";
875 seen +=
MAX2(0., leadLead.second) + leadLead.first->getVehicleType().getLengthWithGap();
876 if (seen > maxLookAhead) {
877 #ifdef DEBUG_CHANGE_OPPOSITE 879 std::cout <<
" cannot changeOpposite due to insufficient free space after columnLeader (seen=" << seen <<
" columnLeader=" << columnLeader.first->getID() <<
")\n";
885 egoGap += columnLeader.first->getVehicleType().getLengthWithGap() + leadLead.second;
886 columnLeader = leadLead;
887 #ifdef DEBUG_CHANGE_OPPOSITE 889 std::cout <<
" new columnLeader=" << columnLeader.first->getID() <<
"\n";
895 #ifdef DEBUG_CHANGE_OPPOSITE 897 std::cout <<
" compute time/space to overtake for columnLeader=" << columnLeader.first->getID() <<
" gap=" << columnLeader.second <<
"\n";
903 #ifdef DEBUG_CHANGE_OPPOSITE 905 std::cout <<
" cannot changeOpposite due to upcoming stop (dist=" << vehicle->
nextStopDist() <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
912 #ifdef DEBUG_CHANGE_OPPOSITE 915 <<
" veh=" << vehicle->
getID()
916 <<
" changeOpposite opposite=" << opposite->
getID()
918 <<
" timeToOvertake=" << timeToOvertake
919 <<
" spaceToOvertake=" << spaceToOvertake
925 if (neighLead.first != 0) {
926 const MSVehicle* oncoming = neighLead.first;
928 #ifdef DEBUG_CHANGE_OPPOSITE 931 <<
" oncoming=" << oncoming->
getID()
932 <<
" oncomingGap=" << neighLead.second
933 <<
" leaderGap=" << leader.second
937 if (neighLead.second - spaceToOvertake - timeToOvertake * oncoming->
getSpeed() < 0) {
939 #ifdef DEBUG_CHANGE_OPPOSITE 941 std::cout <<
" cannot changeOpposite due to dangerous oncoming\n";
959 if (usableDist < spaceToOvertake) {
962 assert(bestLaneConts.size() >= 1);
963 std::vector<MSLane*>::const_iterator it = bestLaneConts.begin() + 1;
964 while (usableDist < spaceToOvertake && it != bestLaneConts.end()) {
965 #ifdef DEBUG_CHANGE_OPPOSITE 967 std::cout <<
" usableDist=" << usableDist <<
" opposite=" <<
Named::getIDSecure((*it)->getOpposite()) <<
"\n";
970 if ((*it)->getOpposite() == 0) {
975 if (*(it - 1) != 0) {
984 #ifdef DEBUG_CHANGE_OPPOSITE 986 std::cout <<
" stop lookahead at link=" << (link == 0 ?
"NULL" : link->
getViaLaneOrLane()->
getID()) <<
" state=" << (link == 0 ?
"?" :
toString(link->getState())) <<
" ignoreRed=" << vehicle->
ignoreRed(link,
true) <<
"\n";
992 usableDist += (*it)->getLength();
996 if (!isOpposite && usableDist < spaceToOvertake) {
997 #ifdef DEBUG_CHANGE_OPPOSITE 999 std::cout <<
" cannot changeOpposite due to insufficient space (seen=" << usableDist <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
1004 #ifdef DEBUG_CHANGE_OPPOSITE 1006 std::cout <<
" usableDist=" << usableDist <<
" spaceToOvertake=" << spaceToOvertake <<
" timeToOvertake=" << timeToOvertake <<
"\n";
1011 std::vector<MSVehicle::LaneQ> preb = vehicle->
getBestLanes();
1026 if (leader.first != 0) {
1028 #ifdef DEBUG_CHANGE_OPPOSITE 1030 std::cout <<
SIMTIME <<
" found oncoming leader=" << leader.first->getID() <<
" gap=" << leader.second <<
"\n";
1035 #ifdef DEBUG_CHANGE_OPPOSITE 1037 std::cout <<
SIMTIME <<
" veh=" << vehicle->
getID() <<
" remaining dist=" << laneQ.
length - forwardPos <<
" forwardPos=" << forwardPos <<
" laneQ.length=" << laneQ.
length <<
"\n";
1042 int state =
checkChange(direction, opposite, leader, neighLead, neighFollow, preb);
1044 bool changingAllowed = (state &
LCA_BLOCKED) == 0;
1057 #ifdef DEBUG_CHANGE_OPPOSITE 1059 std::cout <<
SIMTIME <<
" changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction <<
" opposite=" <<
Named::getIDSecure(opposite) <<
" state=" << state <<
"\n";
1064 #ifdef DEBUG_CHANGE_OPPOSITE 1066 std::cout <<
SIMTIME <<
" not changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction
1084 const double v = vehicle->
getSpeed();
1085 const double u = leader->
getSpeed();
1097 const double sign = -1;
1101 double t = (u - v - sqrt(4 * (u - v) * (u - v) + 8 * a * g) * sign * 0.5) / a;
1106 t = ceil(t /
TS) *
TS;
1109 const double timeToMaxSpeed = (vMax - v) / a;
1111 if (t <= timeToMaxSpeed) {
1113 spaceToOvertake = v * t + t * t * a * 0.5;
1117 const double s = v * timeToMaxSpeed + timeToMaxSpeed * timeToMaxSpeed * a * 0.5;
1118 const double m = timeToMaxSpeed;
1121 t = (g - s + m * vMax) / (vMax - u);
1126 t = ceil(t /
TS) *
TS;
1129 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 isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
double getMinGap() const
Get the free space in front of vehicles of this class.
static MSVehicle * getCloserFollower(const double maxPos, MSVehicle *follow1, MSVehicle *follow2)
return the closer follower of ego
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
MSEdge & getEdge() const
Returns the lane's edge.
double myAngle
the angle in radians (
double getWidth() const
Returns the lane's width.
Representation of a vehicle in the micro simulation.
bool isLinkEnd(MSLinkCont::const_iterator &i) const
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
The action is done to help someone else.
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.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
State myState
This Vehicles driving state (pos and speed)
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
bool hasInfluencer() const
void setLeaderGaps(CLeaderDist, double secGap)
The vehicle is blocked by left follower.
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
bool alreadyChanged() const
reset the flag whether a vehicle already moved to false
bool isStoppedOnLane() const
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
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.
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)
virtual bool changeOpposite(std::pair< MSVehicle *, double > leader)
double getSpeedLat() const
return the lateral speed of the current lane change maneuver
const bool myAllowsChanging
bool mayChange(int direction) const
whether changing to the lane in the given direction should be considered
double myPosLat
the stored lateral position
int getShadowDirection() const
return the direction in which the current shadow lane lies
const bool myChangeToOpposite
whether this edge allows changing to the opposite direction edge
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
Returns the lane's length.
#define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD
MSVehicle * veh(ConstChangerIt ce) const
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
double getPositionOnLane() const
Get the vehicle's position along the lane.
void adaptBestLanesOccupation(int laneIndex, double density)
update occupation from MSLaneChanger
LinkDirection getDirection() const
Returns the direction the vehicle passing this link take.
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) ...
double computeAngle() const
compute the current vehicle angle
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...
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.
MSAbstractLaneChangeModel & getLaneChangeModel()
std::string gDebugSelectedVehicle
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
void saveState(const int dir, const int stateWithoutTraCI, const int state)
The link is a straight direction.
void setFollowerGaps(CLeaderDist follower, double secGap)
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
A class responsible for exchanging messages between cars involved in lane-change interaction.
const std::string & getID() const
Returns the id.
The vehicle changes lanes (micro only)
virtual void updateChanger(bool vehHasChanged)
blocked in all directions
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
The action is urgent (to be defined by lc-model)
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
#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
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
bool isStopped() const
Returns whether the vehicle is at a stop.
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
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.
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'...
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
MSLaneChanger()
Default constructor.
bool isInternal() const
return whether this edge is an internal edge
void updateLanes(SUMOTime t)
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
double nextStopDist() const
return the distance to the next stop or doubleMax if there is none.
std::vector< MSVehicle * > VehCont
Container for vehicles.
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
#define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD
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
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
#define OPPOSITE_OVERTAKING_SAFE_TIMEGAP
double getLength() const
Get vehicle's length [m].
std::pair< const MSVehicle *, double > CLeaderDist
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Influencer & getInfluencer()
Returns the velocity/lane influencer.
LaneChangeAction
The state of a vehicle's lane-change behavior.
bool havePriority() const
Returns whether this link is a major link.
virtual void setOwnState(const int state)
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.
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
The vehicle is blocked being overlapping.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
bool haveRed() const
Returns whether this link is blocked by a red (or redyellow) traffic light.
std::pair< MSVehicle *const, double > getOppositeFollower(const MSVehicle *ego) const
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Changer myChanger
Container for ChangeElemements, one for every lane in the edge.
LinkState getState() const
Returns the current state of the link.
void registerUnchanged(MSVehicle *vehicle)
The vehicle does not have enough space to complete a continuous lane and change before the next turni...
std::pair< MSVehicle *const, double > getRealFollower(const ChangerIt &target) const
The vehicle is blocked by right leader.
MSLane * getLane() const
Returns the lane the vehicle is on.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
bool vehInChanger() const
Check if there is a single change-candidate in the changer. Returns true if there is one...
public emergency vehicles
static SUMOTime gLaneChangeDuration
Representation of a lane in the micro simulation.
double myBackPos
the stored back position
int checkChangeWithinEdge(int laneOffset, const std::pair< MSVehicle *const, double > &leader, const std::vector< MSVehicle::LaneQ > &preb) const
The vehicle is blocked by right follower.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i...
Interface for lane-change models.
std::pair< MSVehicle *const, double > getRealLeader(const ChangerIt &target) const
static const Position INVALID
used to indicate that a position is valid
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
const std::string & getID() const
Returns the name of the vehicle.
double getSpeed() const
Returns the vehicle's current speed.
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
bool ignoreRed(const MSLink *link, bool canBrake) const
decide whether a red (or yellow light) may be ignore