48 #define OPPOSITE_OVERTAKING_SAFE_TIMEGAP 0.0 50 #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD 150.0 // just a guess 52 #define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD 200.0 // just a guess 64 #define DEBUG_COND false 89 for (std::vector<MSLane*>::const_iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
108 const bool haveChanged =
change();
115 ce->lane->releaseVehicles();
129 ce->firstBlocked = 0;
132 ce->lane->getVehiclesSecure();
170 ce->lane->swapAfterLaneChange(t);
171 ce->lane->releaseVehicles();
190 assert(
veh(ce) != 0);
191 assert(
veh(max) != 0);
192 if (
veh(max)->getPositionOnLane() <
veh(ce)->getPositionOnLane()) {
198 assert(
veh(max) != 0);
205 if (direction == 0) {
211 if (direction == -1) {
213 }
else if (direction == 1) {
233 #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;
337 to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
339 to->hoppedVeh = vehicle;
354 MSLane* target = to->lane;
357 to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
359 to->hoppedVeh = vehicle;
361 from->lane->myTmpVehicles.insert(from->lane->myTmpVehicles.begin(), vehicle);
363 from->hoppedVeh = vehicle;
373 shadow->hoppedVeh = vehicle;
377 #ifdef DEBUG_CONTINUE_CHANGE 380 <<
" continueChange veh=" << vehicle->
getID()
382 <<
" dir=" << direction
383 <<
" pastMidpoint=" << pastMidpoint
395 std::pair<MSVehicle* const, double>
399 #ifdef DEBUG_SURROUNDING_VEHICLES 402 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' looks for leader on lc-target lane '" << target->lane->getID() <<
"'." << std::endl;
408 #ifdef DEBUG_SURROUNDING_VEHICLES 410 if (neighLead != 0) {
411 std::cout <<
"Considering '" << neighLead->
getID() <<
"' at position " << neighLead->
getPositionOnLane() << std::endl;
422 if (target->hoppedVeh != 0) {
423 double hoppedPos = target->hoppedVeh->getPositionOnLane();
424 #ifdef DEBUG_SURROUNDING_VEHICLES 426 std::cout <<
"Considering hopped vehicle '" << target->hoppedVeh->getID() <<
"' at position " << hoppedPos << std::endl;
430 neighLead = target->hoppedVeh;
434 if (neighLead == 0) {
435 #ifdef DEBUG_SURROUNDING_VEHICLES 437 std::cout <<
"Looking for leader on consecutive lanes." << std::endl;
441 MSLane* targetLane = target->lane;
444 std::vector<MSVehicle*>::const_iterator i = targetLane->
myPartialVehicles.begin();
459 return std::pair<MSVehicle* const, double>(
static_cast<MSVehicle*
>(0), -1);
462 return target->lane->getLeaderOnConsecutive(dist, seen, speed, *
veh(
myCandi), bestLaneConts);
470 std::pair<MSVehicle* const, double>
474 #ifdef DEBUG_SURROUNDING_VEHICLES 477 std::cout <<
SIMTIME <<
" veh '" << vehicle->
getID() <<
"' looks for follower on lc-target lane '" << target->lane->getID() <<
"'." << std::endl;
484 #ifdef DEBUG_SURROUNDING_VEHICLES 486 if (neighFollow != 0) {
487 std::cout <<
"veh(target) returns '" << neighFollow->
getID() <<
"' at position " << neighFollow->
getPositionOnLane() << std::endl;
489 std::cout <<
"veh(target) returns none." << std::endl;
495 #ifdef DEBUG_SURROUNDING_VEHICLES 497 if (
getCloserFollower(candiPos, neighFollow, target->hoppedVeh) != neighFollow) {
498 std::cout <<
"Hopped vehicle '" << target->hoppedVeh->getID() <<
"' at position " << target->hoppedVeh->getPositionOnLane() <<
" is closer." << std::endl;
507 #ifdef DEBUG_SURROUNDING_VEHICLES 510 if (partialBehind != 0 && partialBehind != neighFollow) {
511 std::cout <<
"'Partial behind'-vehicle '" << target->lane->getPartialBehind(candi)->
getID() <<
"' at position " << target->hoppedVeh->getPositionOnLane() <<
" is closer." << std::endl;
516 neighFollow =
getCloserFollower(candiPos, neighFollow, target->lane->getPartialBehind(candi));
518 if (neighFollow == 0) {
520 #ifdef DEBUG_SURROUNDING_VEHICLES 522 if (consecutiveFollower.first == 0) {
523 std::cout <<
"no follower found." << std::endl;
525 std::cout <<
"found follower '" << consecutiveFollower.first->
getID() <<
"' on consecutive lanes." << std::endl;
529 return std::make_pair(const_cast<MSVehicle*>(consecutiveFollower.first), consecutiveFollower.second);
531 #ifdef DEBUG_SURROUNDING_VEHICLES 533 std::cout <<
"found follower '" << neighFollow->
getID() <<
"'." << std::endl;
537 return std::pair<MSVehicle* const, double>(neighFollow,
561 const std::pair<MSVehicle* const, double>& leader,
562 const std::vector<MSVehicle::LaneQ>& preb)
const {
566 if (neighLead.first != 0 && neighLead.first == neighFollow.first) {
569 neighFollow.first = 0;
572 return checkChange(laneOffset, target->lane, leader, neighLead, neighFollow, preb);
579 const std::pair<MSVehicle* const, double>& leader,
580 const std::pair<MSVehicle* const, double>& neighLead,
581 const std::pair<MSVehicle* const, double>& neighFollow,
582 const std::vector<MSVehicle::LaneQ>& preb)
const {
587 #ifdef DEBUG_CHECK_CHANGE 590 <<
"\n" <<
SIMTIME <<
" checkChange() for vehicle '" << vehicle->
getID() <<
"'" 600 if (neighFollow.first != 0 && neighFollow.second < 0) {
604 #ifdef DEBUG_CHECK_CHANGE 607 <<
" overlapping with follower..." 613 if (neighLead.first != 0 && neighLead.second < 0) {
617 #ifdef DEBUG_CHECK_CHANGE 620 <<
" overlapping with leader..." 628 if ((blocked & blockedByFollower) == 0 && neighFollow.first != 0) {
631 blocked |= blockedByFollower;
634 #ifdef DEBUG_CHECK_CHANGE 637 <<
" back gap unsafe: " 638 <<
"gap = " << neighFollow.second
640 << neighFollow.first->getCarFollowModel().getSecureGap(neighFollow.first->getSpeed(),
650 if ((blocked & blockedByLeader) == 0 && neighLead.first != 0) {
653 blocked |= blockedByLeader;
656 #ifdef DEBUG_CHECK_CHANGE 659 <<
" front gap unsafe: " 660 <<
"gap = " << neighLead.second
663 neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())
674 laneOffset, msg, blocked, leader, neighLead, neighFollow, *targetLane, preb, &(
myCandi->lastBlocked), &(
myCandi->firstBlocked));
680 const double speed = vehicle->
getSpeed();
683 std::pair<MSVehicle* const, double> neighLead2 = targetLane->
getCriticalLeader(dist, seen, speed, *vehicle);
684 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
686 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
687 state |= blockedByLeader;
691 if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
694 state |= blockedByLeader;
703 const double avgSpeed = 0.5 * (
711 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
712 while (!nextLane->
isLinkEnd(link) && seen <= space2change) {
716 || (nextLane->
getEdge().
isInternal() && (*link)->getViaLaneOrLane()->getEdge().isInternal())
721 if ((*link)->getViaLane() == 0) {
724 nextLane = (*link)->getViaLaneOrLane();
729 if (nextLane->
isLinkEnd(link) && seen < space2change) {
730 #ifdef DEBUG_CHECK_CHANGE 732 std::cout <<
SIMTIME <<
" checkChange insufficientSpace: seen=" << seen <<
" space2change=" << space2change <<
"\n";
738 if ((state & LCA_BLOCKED) == 0) {
741 const double speed = vehicle->
getSpeed();
746 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
747 while (!nextLane->
isLinkEnd(link) && seen <= space2change && seen <= dist) {
748 nextLane = (*link)->getViaLaneOrLane();
750 if (targetLane == 0) {
754 std::pair<MSVehicle* const, double> neighLead2 = targetLane->
getLeader(vehicle, -seen, std::vector<MSLane*>());
755 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
757 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
758 state |= blockedByLeader;
762 if ((*link)->getViaLane() == 0) {
771 const int oldstate = state;
776 #ifdef DEBUG_CHECK_CHANGE 779 <<
" veh=" << vehicle->
getID()
806 if (!isOpposite && leader.first == 0) {
818 int direction = isOpposite ? -1 : 1;
819 std::pair<MSVehicle*, double> neighLead((
MSVehicle*)0, -1);
822 double timeToOvertake;
823 double spaceToOvertake;
825 assert(leader.first != 0);
829 std::pair<MSVehicle*, double> columnLeader = leader;
830 double egoGap = leader.second;
831 bool foundSpaceAhead =
false;
832 double seen = leader.second + leader.first->getVehicleType().getLengthWithGap();
834 while (!foundSpaceAhead) {
835 const double requiredSpaceAfterLeader = (columnLeader.first->getCarFollowModel().getSecureGap(
841 const bool checkTmpVehicles = (&columnLeader.first->getLane()->getEdge() == &source->
getEdge());
842 std::pair<MSVehicle* const, double> leadLead = columnLeader.first->getLane()->getLeader(
843 columnLeader.first, columnLeader.first->getPositionOnLane(), conts, requiredSpaceAfterLeader + mergeBrakeGap,
846 #ifdef DEBUG_CHANGE_OPPOSITE 848 std::cout <<
" leadLead=" <<
Named::getIDSecure(leadLead.first) <<
" gap=" << leadLead.second <<
"\n";
851 if (leadLead.first == 0) {
852 foundSpaceAhead =
true;
854 const double requiredSpace = (requiredSpaceAfterLeader
855 + vehicle->
getCarFollowModel().
getSecureGap(overtakingSpeed, leadLead.first->getSpeed(), leadLead.first->getCarFollowModel().getMaxDecel()));
856 if (leadLead.second > requiredSpace) {
857 foundSpaceAhead =
true;
859 #ifdef DEBUG_CHANGE_OPPOSITE 861 std::cout <<
" not enough space after columnLeader=" << columnLeader.first->getID() <<
" required=" << requiredSpace <<
"\n";
864 seen +=
MAX2(0., leadLead.second) + leadLead.first->getVehicleType().getLengthWithGap();
866 #ifdef DEBUG_CHANGE_OPPOSITE 868 std::cout <<
" cannot changeOpposite due to insufficient free space after columnLeader (seen=" << seen <<
" columnLeader=" << columnLeader.first->getID() <<
")\n";
874 egoGap += columnLeader.first->getVehicleType().getLengthWithGap() + leadLead.second;
875 columnLeader = leadLead;
876 #ifdef DEBUG_CHANGE_OPPOSITE 878 std::cout <<
" new columnLeader=" << columnLeader.first->getID() <<
"\n";
884 #ifdef DEBUG_CHANGE_OPPOSITE 886 std::cout <<
" compute time/space to overtake for columnLeader=" << columnLeader.first->getID() <<
" gap=" << columnLeader.second <<
"\n";
892 #ifdef DEBUG_CHANGE_OPPOSITE 894 std::cout <<
" cannot changeOpposite due to upcoming stop (dist=" << vehicle->
nextStopDist() <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
901 #ifdef DEBUG_CHANGE_OPPOSITE 904 <<
" veh=" << vehicle->
getID()
905 <<
" changeOpposite opposite=" << opposite->
getID()
907 <<
" timeToOvertake=" << timeToOvertake
908 <<
" spaceToOvertake=" << spaceToOvertake
914 if (neighLead.first != 0) {
915 const MSVehicle* oncoming = neighLead.first;
917 #ifdef DEBUG_CHANGE_OPPOSITE 920 <<
" oncoming=" << oncoming->
getID()
921 <<
" oncomingGap=" << neighLead.second
922 <<
" leaderGap=" << leader.second
926 if (neighLead.second - spaceToOvertake - timeToOvertake * oncoming->
getSpeed() < 0) {
928 #ifdef DEBUG_CHANGE_OPPOSITE 930 std::cout <<
" cannot changeOpposite due to dangerous oncoming\n";
948 if (usableDist < spaceToOvertake) {
951 assert(bestLaneConts.size() >= 1);
952 std::vector<MSLane*>::const_iterator it = bestLaneConts.begin() + 1;
953 while (usableDist < spaceToOvertake && it != bestLaneConts.end()) {
954 #ifdef DEBUG_CHANGE_OPPOSITE 956 std::cout <<
" usableDist=" << usableDist <<
" opposite=" <<
Named::getIDSecure((*it)->getOpposite()) <<
"\n";
959 if ((*it)->getOpposite() == 0) {
964 if (*(it - 1) != 0) {
970 usableDist += (*it)->getLength();
974 if (!isOpposite && usableDist < spaceToOvertake) {
975 #ifdef DEBUG_CHANGE_OPPOSITE 977 std::cout <<
" cannot changeOpposite due to insufficient space (seen=" << usableDist <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
982 #ifdef DEBUG_CHANGE_OPPOSITE 984 std::cout <<
" usableDist=" << usableDist <<
" spaceToOvertake=" << spaceToOvertake <<
" timeToOvertake=" << timeToOvertake <<
"\n";
989 std::vector<MSVehicle::LaneQ> preb = vehicle->
getBestLanes();
1004 if (leader.first != 0) {
1006 #ifdef DEBUG_CHANGE_OPPOSITE 1008 std::cout <<
SIMTIME <<
" found oncoming leader=" << leader.first->getID() <<
" gap=" << leader.second <<
"\n";
1013 #ifdef DEBUG_CHANGE_OPPOSITE 1015 std::cout <<
SIMTIME <<
" veh=" << vehicle->
getID() <<
" remaining dist=" << laneQ.
length - forwardPos <<
" forwardPos=" << forwardPos <<
" laneQ.length=" << laneQ.
length <<
"\n";
1020 int state =
checkChange(direction, opposite, leader, neighLead, neighFollow, preb);
1022 bool changingAllowed = (state &
LCA_BLOCKED) == 0;
1035 #ifdef DEBUG_CHANGE_OPPOSITE 1037 std::cout <<
SIMTIME <<
" changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction <<
" opposite=" <<
Named::getIDSecure(opposite) <<
" state=" << state <<
"\n";
1042 #ifdef DEBUG_CHANGE_OPPOSITE 1044 std::cout <<
SIMTIME <<
" not changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction
1062 const double v = vehicle->
getSpeed();
1063 const double u = leader->
getSpeed();
1075 const double sign = -1;
1079 double t = (u - v - sqrt(4 * (u - v) * (u - v) + 8 * a * g) * sign * 0.5) / a;
1084 t = ceil(t /
TS) *
TS;
1087 const double timeToMaxSpeed = (vMax - v) / a;
1089 if (t <= timeToMaxSpeed) {
1091 spaceToOvertake = v * t + t * t * a * 0.5;
1095 const double s = v * timeToMaxSpeed + timeToMaxSpeed * timeToMaxSpeed * a * 0.5;
1096 const double m = timeToMaxSpeed;
1099 t = (g - s + m * vMax) / (vMax - u);
1104 t = ceil(t /
TS) *
TS;
1107 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 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, assuming that during...
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.
The action is done to help someone else.
LinkDirection getDirection() const
Returns the direction the vehicle passing this link take.
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
State myState
This Vehicles driving state (pos and speed)
MSLane * getLane() const
Returns the lane the vehicle is on.
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...
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
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
void adaptBestLanesOccupation(int laneIndex, double density)
update occupation from MSLaneChanger
bool alreadyChanged() const
reset the flag whether a vehicle already moved to false
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.
MSAbstractLaneChangeModel & getLaneChangeModel()
std::string gDebugSelectedVehicle
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.
void saveState(const int dir, const int stateWithoutTraCI, const int state)
The link is a straight direction.
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
A class responsible for exchanging messages between cars involved in lane-change interaction.
The vehicle changes lanes (micro only)
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
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)
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.
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.
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'...
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].
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.
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
#define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
#define OPPOSITE_OVERTAKING_SAFE_TIMEGAP
std::pair< const MSVehicle *, double > CLeaderDist
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.
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.
The vehicle is blocked being overlapping.
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
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.
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 vehicles 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)
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
double getLateralSpeed() const
return the lateral speed of the current lane change maneuver
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
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)