42 #ifdef CHECK_MEMORY_LEAKS 44 #endif // CHECK_MEMORY_LEAKS 52 #define LOOK_FORWARD_SPEED_DIVIDER (SUMOReal)14. 54 #define LOOK_FORWARD_RIGHT (SUMOReal)10. 55 #define LOOK_FORWARD_LEFT (SUMOReal)20. 57 #define JAM_FACTOR (SUMOReal)1. 59 #define LCA_RIGHT_IMPATIENCE (SUMOReal)-1. 60 #define CUT_IN_LEFT_SPEED_THRESHOLD (SUMOReal)27. 62 #define LOOK_AHEAD_MIN_SPEED (SUMOReal)0.0 63 #define LOOK_AHEAD_SPEED_MEMORY (SUMOReal)0.9 64 #define LOOK_AHEAD_SPEED_DECREMENT 6. 66 #define HELP_DECEL_FACTOR (SUMOReal)1.0 68 #define HELP_OVERTAKE (SUMOReal)(10.0 / 3.6) 69 #define MIN_FALLBEHIND (SUMOReal)(14.0 / 3.6) 71 #define URGENCY (SUMOReal)2.0 73 #define ROUNDABOUT_DIST_BONUS (SUMOReal)80.0 75 #define CHANGE_PROB_THRESHOLD_RIGHT (SUMOReal)2.0 76 #define CHANGE_PROB_THRESHOLD_LEFT (SUMOReal)0.2 77 #define KEEP_RIGHT_TIME (SUMOReal)5.0 // the number of seconds after which a vehicle should move to the right lane 78 #define KEEP_RIGHT_ACCEPTANCE (SUMOReal)2.0 // calibration factor for determining the desire to keep right 80 #define RELGAIN_NORMALIZATION_MIN_SPEED (SUMOReal)10.0 87 mySpeedGainProbability(0),
88 myKeepRightProbability(0),
89 myLeadingBlockerLength(0),
104 const std::pair<MSVehicle*, SUMOReal>& leader,
105 const std::pair<MSVehicle*, SUMOReal>& neighLead,
106 const std::pair<MSVehicle*, SUMOReal>& neighFollow,
108 const std::vector<MSVehicle::LaneQ>& preb,
111 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
138 return MAX2(min, safe);
145 for (std::vector<SUMOReal>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
147 if (v >= min && v <= max) {
148 nVSafe =
MIN2(v, nVSafe);
163 return (max + wanted) / (
SUMOReal) 2.0;
167 return (min + wanted) / (
SUMOReal) 2.0;
170 return (max + wanted) / (
SUMOReal) 2.0;
178 return (max + wanted) / (
SUMOReal) 2.0;
205 const std::pair<MSVehicle*, SUMOReal>& neighLead,
209 for (std::vector<SUMOReal>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
212 plannedSpeed =
MIN2(plannedSpeed, v);
216 assert(neighLead.first != 0);
220 const SUMOReal overtakeDist = (neighLead.second
232 || dv * remainingSeconds < overtakeDist) {
255 }
else if (neighLead.first != 0) {
263 return MIN2(targetSpeed, plannedSpeed);
275 const std::pair<MSVehicle*, SUMOReal>& neighFollow,
279 assert(neighFollow.first != 0);
285 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
303 const SUMOReal dv = plannedSpeed - neighNewSpeed1s;
305 const SUMOReal decelGap = neighFollow.second + dv;
307 if (decelGap > 0 && decelGap >= secureGap) {
317 assert(vsafe <= vsafe1);
319 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap +
POSITION_EPS)) {
340 const SUMOReal overtakeDist = (neighFollow.second
346 const SUMOReal needDV = overtakeDist / remainingSeconds;
391 const std::pair<MSVehicle*, SUMOReal>& leader,
392 const std::pair<MSVehicle*, SUMOReal>& neighLead,
393 const std::pair<MSVehicle*, SUMOReal>& neighFollow,
395 const std::vector<MSVehicle::LaneQ>& preb,
398 assert(laneOffset == 1 || laneOffset == -1);
402 int bestLaneOffset = 0;
411 for (
int p = 0; p < (int) preb.size(); ++p) {
412 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
413 assert(p + laneOffset < (
int)preb.size());
415 neigh = preb[p + laneOffset];
416 currentDist = curr.
length;
418 bestLaneOffset = curr.bestLaneOffset;
419 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
420 bestLaneOffset = laneOffset;
422 best = preb[p + bestLaneOffset];
428 const bool right = (laneOffset == -1);
432 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
438 if (lastBlocked != firstBlocked) {
465 if (bestLaneOffset == 0 && leader.first != 0 && leader.first->isStopped()) {
468 + leader.first->getVehicleType().getLengthWithGap());
478 int roundaboutEdgesAhead = 0;
480 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
481 roundaboutEdgesAhead += 1;
482 }
else if (roundaboutEdgesAhead > 0) {
487 int roundaboutEdgesAheadNeigh = 0;
489 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
490 roundaboutEdgesAheadNeigh += 1;
491 }
else if (roundaboutEdgesAheadNeigh > 0) {
496 if (roundaboutEdgesAhead > 1) {
502 const SUMOReal maxJam =
MAX2(preb[currIdx + laneOffset].occupation, preb[currIdx].occupation);
533 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
543 if ((ret & lcaCounter) != 0) {
555 if (changeToBest &&
abs(bestLaneOffset) > 1) {
563 if (*firstBlocked != neighLead.first) {
570 const SUMOReal plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
571 if (plannedSpeed >= 0) {
573 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
579 if (roundaboutEdgesAhead > 1) {
636 if (neighLead.first == 0) {
641 &
myVehicle,
myVehicle.
getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
643 if (leader.first == 0) {
651 thisLaneVSafe =
MIN2(thisLaneVSafe, vMax);
652 neighLaneVSafe =
MIN2(neighLaneVSafe, vMax);
653 const SUMOReal relativeGain = (neighLaneVSafe - thisLaneVSafe) /
MAX2(neighLaneVSafe,
658 if (thisLaneVSafe - 5 / 3.6 > neighLaneVSafe) {
670 if (mySpeedGainProbability < 0 || relativeGain > 0) {
679 SUMOReal fullSpeedDrivingSeconds =
MIN2(acceptanceTime, fullSpeedGap / vMax);
680 if (neighLead.first != 0 && neighLead.first->getSpeed() < vMax) {
683 vMax, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())));
684 fullSpeedDrivingSeconds =
MIN2(fullSpeedDrivingSeconds, fullSpeedGap / (vMax - neighLead.first->getSpeed()));
695 <<
" neighDist=" << neighDist
697 <<
" leaderSpeed=" << (neighLead.first == 0 ? -1 : neighLead.first->getSpeed())
699 myVehicle.
getSpeed(), neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()))
700 <<
" acceptanceTime=" << acceptanceTime
701 <<
" fullSpeedGap=" << fullSpeedGap
702 <<
" fullSpeedDrivingSeconds=" << fullSpeedDrivingSeconds
703 <<
" dProb=" << deltaProb
723 if (thisLaneVSafe > neighLaneVSafe) {
741 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
756 if ((*blocked) != 0) {
768 (*blocked)->getCarFollowModel().getMaxDecel()));
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
#define CHANGE_PROB_THRESHOLD_RIGHT
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
SUMOReal getMaxSpeed() const
Get vehicle's maximum speed [m/s].
MSLCM_LC2013(MSVehicle &v)
int wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, SUMOReal > &leader, const std::pair< MSVehicle *, SUMOReal > &neighLead, const std::pair< MSVehicle *, SUMOReal > &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...
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
SUMOReal patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel &cfModel)
Called to adapt the speed in order to allow a lane change.
#define LOOK_FORWARD_RIGHT
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
The action is done to help someone else.
SUMOReal getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle's follow speed (no dawdling)
#define KEEP_RIGHT_ACCEPTANCE
The car-following model abstraction.
SUMOReal myKeepRightProbability
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
SUMOReal getLength() const
Get vehicle's length [m].
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
SUMOReal getSecureGap(const SUMOReal speed, const SUMOReal leaderSpeed, const SUMOReal leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum.
void initLastLaneChangeOffset(int dir)
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
std::vector< SUMOReal > myVSafes
The action is due to a TraCI request.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
The action is urgent (to be defined by lc-model)
void informFollower(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, SUMOReal > &neighFollow, SUMOReal remainingSeconds, SUMOReal plannedSpeed)
decide whether we will try cut in before the follower or allow to be overtaken
MSAbstractLaneChangeModel & getLaneChangeModel()
#define ROUNDABOUT_DIST_BONUS
static bool myAllowOvertakingRight
whether overtaking on the right is permitted
A class responsible for exchanging messages between cars involved in lane-change interaction.
bool currentDistDisallows(SUMOReal dist, int laneOffset, SUMOReal lookForwardDist)
bool currentDistAllows(SUMOReal dist, int laneOffset, SUMOReal lookForwardDist)
bool cancelRequest(int state)
whether the influencer cancels the given request
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver's reaction time.
SUMOReal myLeadingBlockerLength
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
#define CUT_IN_LEFT_SPEED_THRESHOLD
SUMOReal myLookAheadSpeed
#define LOOK_AHEAD_SPEED_MEMORY
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
#define CHANGE_PROB_THRESHOLD_LEFT
#define RELGAIN_NORMALIZATION_MIN_SPEED
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap2pred) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling) ...
SUMOReal getSpeedLimit() const
Returns the lane's maximum allowed speed.
A structure representing the best lanes for continuing the route.
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
int myOwnState
The current state of the vehicle.
SUMOReal informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, SUMOReal > &neighLead, SUMOReal remainingSeconds)
virtual void saveBlockerLength(SUMOReal length)
reserve space at the end of the lane to avoid dead locks
std::pair< SUMOReal, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
int _wantsChange(int laneOffset, MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, const std::pair< MSVehicle *, SUMOReal > &leader, const std::pair< MSVehicle *, SUMOReal > &neighLead, const std::pair< MSVehicle *, SUMOReal > &neighFollow, const MSLane &neighLane, const std::vector< MSVehicle::LaneQ > &preb, MSVehicle **lastBlocked, MSVehicle **firstBlocked)
helper function for doing the actual work
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
The action is needed to follow the route (navigational lc)
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Influencer & getInfluencer()
Returns the velocity/lane influencer.
SUMOReal occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
The action is due to the default of keeping right "Rechtsfahrgebot".
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Needs to stay on the current lane.
SUMOReal getSpeed() const
Returns the vehicle's current speed.
SUMOReal getWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s)
#define LOOK_FORWARD_LEFT
SUMOReal mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial ...
bool amBlockingFollowerPlusNB()
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
SUMOReal _patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel &cfModel)
#define LOOK_AHEAD_MIN_SPEED
#define LCA_RIGHT_IMPATIENCE
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
MSLane * getLane() const
Returns the lane the vehicle is on.
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
The edge is an internal edge.
void * inform(void *info, MSVehicle *sender)
Representation of a lane in the micro simulation.
const MSCFModel & myCarFollowModel
The vehicle's car following model.
Interface for lane-change models.
int getBestLaneOffset() const
returns the current offset from the best lane
#define HELP_DECEL_FACTOR
const std::string & getID() const
Returns the name of the vehicle.
The action is due to the wish to be faster (tactical lc)