39 #ifdef CHECK_MEMORY_LEAKS
41 #endif // CHECK_MEMORY_LEAKS
44 #ifdef DEBUG_VEHICLE_GUI_SELECTION
56 #define LOOK_FORWARD_SPEED_DIVIDER (SUMOReal)14.
62 #define LOOK_FORWARD_RIGHT (SUMOReal)10.
63 #define LOOK_FORWARD_LEFT (SUMOReal)20.
65 #define JAM_FACTOR (SUMOReal)1.
68 #define LCA_RIGHT_IMPATIENCE (SUMOReal)-1.
69 #define CUT_IN_LEFT_SPEED_THRESHOLD (SUMOReal)27.
71 #define LOOK_AHEAD_MIN_SPEED (SUMOReal)0.0
72 #define LOOK_AHEAD_SPEED_MEMORY (SUMOReal)0.9
73 #define LOOK_AHEAD_SPEED_DECREMENT 6.
75 #define HELP_DECEL_FACTOR (SUMOReal)1.0
77 #define HELP_OVERTAKE (SUMOReal)(10.0 / 3.6)
78 #define MIN_FALLBEHIND (SUMOReal)(14.0 / 3.6)
80 #define KEEP_RIGHT_HEADWAY (SUMOReal)2.0
82 #define URGENCY (SUMOReal)2.0
84 #define ROUNDABOUT_DIST_BONUS (SUMOReal)80.0
90 #define DEBUG_COND false
95 return v == 0 ?
"NULL" : v->
getID();
104 mySpeedGainProbability(0),
105 myKeepRightProbability(0),
106 myLeadingBlockerLength(0),
121 const std::pair<MSVehicle*, SUMOReal>& leader,
122 const std::pair<MSVehicle*, SUMOReal>& neighLead,
123 const std::pair<MSVehicle*, SUMOReal>& neighFollow,
125 const std::vector<MSVehicle::LaneQ>& preb,
136 <<
" considerChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
140 const int result =
_wantsChange(laneOffset, msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked);
145 <<
" wantsChangeTo=" << (laneOffset == -1 ?
"right" :
"left")
152 << ((result &
LCA_TRACI) ?
" (traci)" :
"")
169 const std::string patched = (wanted != newSpeed ?
" patched=" +
toString(newSpeed) :
"");
175 <<
" wanted=" << wanted
206 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" slowing down for leading blocker" << (safe < min ?
" (not enough)" :
"") <<
"\n";
208 return MAX2(min, safe);
215 for (std::vector<SUMOReal>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
217 if (v >= min && v <= max) {
218 nVSafe =
MIN2(v, nVSafe);
221 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" got nVSafe=" << nVSafe <<
"\n";
226 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" ignoring low nVSafe=" << v <<
" min=" << min <<
"\n";
230 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" ignoring high nVSafe=" << v <<
" max=" << max <<
"\n";
238 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" got vSafe\n";
249 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_WANTS_LANECHANGE (strat, no vSafe)\n";
251 return (max + wanted) / (
SUMOReal) 2.0;
256 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_BLOCKED_BY_LEADER (coop)\n";
258 return (min + wanted) / (
SUMOReal) 2.0;
262 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_BLOCKED_BY_FOLLOWER (coop)\n";
264 return (max + wanted) / (
SUMOReal) 2.0;
306 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_AMBLOCKINGLEADER\n";
308 return (max + wanted) / (
SUMOReal) 2.0;
313 std::cout << time <<
" veh=" <<
myVehicle.
getID() <<
" LCA_AMBLOCKINGFOLLOWER_DONTBRAKE\n";
334 if (pinfo->first >= 0) {
342 <<
" informedBy=" << sender->
getID()
343 <<
" info=" << pinfo->second
344 <<
" vSafe=" << pinfo->first
356 const std::pair<MSVehicle*, SUMOReal>& neighLead,
360 for (std::vector<SUMOReal>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
363 plannedSpeed =
MIN2(plannedSpeed, v);
367 std::cout <<
" informLeader speed=" <<
myVehicle.
getSpeed() <<
" planned=" << plannedSpeed <<
"\n";
371 assert(neighLead.first != 0);
377 const SUMOReal overtakeDist = (neighLead.second
389 || dv * remainingSeconds < overtakeDist) {
402 <<
" cannot overtake leader nv=" << nv->
getID()
404 <<
" remainingSeconds=" << remainingSeconds
405 <<
" targetSpeed=" << targetSpeed
406 <<
" nextSpeed=" << nextSpeed
415 <<
" cannot overtake fast leader nv=" << nv->
getID()
417 <<
" remainingSeconds=" << remainingSeconds
418 <<
" targetSpeed=" << targetSpeed
427 <<
" wants to overtake leader nv=" << nv->
getID()
429 <<
" remainingSeconds=" << remainingSeconds
430 <<
" currentGap=" << neighLead.second
438 }
else if (neighLead.first != 0) {
447 std::cout <<
" not blocked by leader nv=" << nv->
getID()
449 <<
" gap=" << neighLead.second
450 <<
" nextGap=" << neighLead.second - dv
452 <<
" targetSpeed=" << targetSpeed
455 return MIN2(targetSpeed, plannedSpeed);
467 const std::pair<MSVehicle*, SUMOReal>& neighFollow,
471 assert(neighFollow.first != 0);
479 if ((neededGap - neighFollow.second) / remainingSeconds < (plannedSpeed - nv->
getSpeed())) {
481 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" without any help neededGap=" << neededGap <<
"\n";
500 const SUMOReal dv = plannedSpeed - neighNewSpeed1s;
502 const SUMOReal decelGap = neighFollow.second + dv;
507 <<
" egoNV=" << plannedSpeed
508 <<
" nvNewSpeed=" << neighNewSpeed
509 <<
" nvNewSpeed1s=" << neighNewSpeed1s
510 <<
" deltaGap=" << dv
511 <<
" decelGap=" << decelGap
512 <<
" secGap=" << secureGap
515 if (decelGap > 0 && decelGap >= secureGap) {
522 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
"\n";
524 }
else if (dv > 0 && dv * remainingSeconds > (secureGap - decelGap +
POSITION_EPS)) {
528 std::cout <<
" wants to cut in before nv=" << nv->
getID() <<
" (eventually)\n";
540 std::cout <<
" wants right follower to slow down a bit\n";
544 std::cout <<
" wants to cut in before right follower nv=" << nv->
getID() <<
" (eventually)\n";
552 const SUMOReal overtakeDist = (neighFollow.second
558 const SUMOReal needDV = overtakeDist / remainingSeconds;
565 <<
" wants to be overtaken by=" << nv->
getID()
566 <<
" overtakeDist=" << overtakeDist
568 <<
" vhelp=" << vhelp
613 const std::pair<MSVehicle*, SUMOReal>& leader,
614 const std::pair<MSVehicle*, SUMOReal>& neighLead,
615 const std::pair<MSVehicle*, SUMOReal>& neighFollow,
617 const std::vector<MSVehicle::LaneQ>& preb,
620 assert(laneOffset == 1 || laneOffset == -1);
624 int bestLaneOffset = 0;
633 for (
int p = 0; p < (
int) preb.size(); ++p) {
634 if (preb[p].lane == prebLane && p + laneOffset >= 0) {
635 assert(p + laneOffset < (
int)preb.size());
637 neigh = preb[p + laneOffset];
638 currentDist = curr.
length;
640 bestLaneOffset = curr.bestLaneOffset;
642 if (bestLaneOffset == 0 && preb[p + laneOffset].bestLaneOffset == 0) {
646 <<
" bestLaneOffsetOld=" << bestLaneOffset
647 <<
" bestLaneOffsetNew=" << laneOffset
650 bestLaneOffset = laneOffset;
652 best = preb[p + bestLaneOffset];
658 const bool right = (laneOffset == -1);
663 const bool changeToBest = (right && bestLaneOffset < 0) || (!right && bestLaneOffset > 0);
686 <<
" firstBlocked=" <<
tryID(*firstBlocked)
687 <<
" lastBlocked=" <<
tryID(*lastBlocked)
688 <<
" neighLead=" <<
tryID(neighLead.first)
689 <<
" neighLeadGap=" << neighLead.second
690 <<
" neighFollow=" <<
tryID(neighFollow.first)
691 <<
" neighFollowGap=" << neighFollow.second
697 if (lastBlocked != firstBlocked) {
736 int roundaboutEdgesAhead = 0;
738 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
739 roundaboutEdgesAhead += 1;
740 }
else if (roundaboutEdgesAhead > 0) {
745 int roundaboutEdgesAheadNeigh = 0;
747 if ((*it) != 0 && (*it)->getEdge().isRoundabout()) {
748 roundaboutEdgesAheadNeigh += 1;
749 }
else if (roundaboutEdgesAheadNeigh > 0) {
754 if (roundaboutEdgesAhead > 1) {
758 if (roundaboutEdgesAhead > 0) {
760 std::cout <<
" roundaboutEdgesAhead=" << roundaboutEdgesAhead <<
" roundaboutEdgesAheadNeigh=" << roundaboutEdgesAheadNeigh <<
"\n";
766 const SUMOReal maxJam =
MAX2(preb[currIdx + laneOffset].occupation, preb[currIdx].occupation);
773 <<
" laDist=" << laDist
774 <<
" currentDist=" << currentDist
775 <<
" usableDist=" << usableDist
776 <<
" bestLaneOffset=" << bestLaneOffset
777 <<
" best.length=" << best.
length
797 <<
" avoid overtaking on the right nv=" << nv->
getID()
800 <<
" plannedSpeed=" <<
myVSafes.back()
814 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (1) neighLeftPlace=" << neighLeftPlace <<
"\n";
817 }
else if (bestLaneOffset == 0 && (neighLeftPlace * 2. < laDist)) {
823 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" could not change back and forth in time (2) neighLeftPlace=" << neighLeftPlace <<
"\n";
833 if ((ret & lcaCounter) != 0) {
838 std::cout <<
" retAfterInfluence=" << ret <<
"\n";
848 if (changeToBest &&
abs(bestLaneOffset) > 1) {
851 std::cout <<
" reserving space for unseen blockers\n";
859 if (*firstBlocked != neighLead.first) {
866 const SUMOReal plannedSpeed =
informLeader(msgPass, blocked, myLca, neighLead, remainingSeconds);
867 if (plannedSpeed >= 0) {
869 informFollower(msgPass, blocked, myLca, neighFollow, remainingSeconds, plannedSpeed);
876 <<
" remainingSeconds=" << remainingSeconds
877 <<
" plannedSpeed=" << plannedSpeed
884 if (roundaboutEdgesAhead > 1) {
899 std::cout <<
" veh=" <<
myVehicle.
getID() <<
" does not want to get stranded on the on-ramp of a highway\n";
921 <<
" wantsChangeToHelp=" << (right ?
"right" :
"left")
923 << (((
myOwnState & myLcaCounter) != 0) ?
" (counter)" :
"")
945 if (neighLead.first == 0) {
950 &
myVehicle,
myVehicle.
getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()));
952 if (leader.first == 0) {
964 if (thisLaneVSafe - neighLaneVSafe > 5. / 3.6) {
983 <<
" thisLaneVSafe=" << thisLaneVSafe
984 <<
" neighLaneVSafe=" << neighLaneVSafe
997 if (thisLaneVSafe > neighLaneVSafe) {
1021 && (right ? mySpeedGainProbability < 0 : mySpeedGainProbability > 0)) {
1030 <<
" thisLaneVSafe=" << thisLaneVSafe
1031 <<
" neighLaneVSafe=" << neighLaneVSafe
1051 if ((*blocked) != 0) {
1056 <<
" blocked=" <<
tryID(*blocked)
1075 (*blocked)->getCarFollowModel().getMaxDecel()));
1096 <<
" blocker=" <<
tryID(blocker)
1106 <<
" blocker=" <<
tryID(blocker)
void * inform(void *info, MSVehicle *sender)
#define LOOK_AHEAD_MIN_SPEED
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
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].
static bool gDebugFlag1
global utility flags for debugging
int slowDownForBlocked(MSVehicle **blocked, int state)
compute useful slowdowns for blocked vehicles
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
bool currentDistAllows(SUMOReal dist, int laneOffset, SUMOReal lookForwardDist)
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 safe speed (no dawdling)
SUMOReal myLeadingBlockerLength
The car-following model abstraction.
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
SUMOReal getLength() const
Get vehicle's length [m].
void keepRight(MSVehicle *neigh)
updated myKeepRightProbability and mySpeedGainProbability if the right neighbours are faster ...
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...
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSLCM_JE2013(MSVehicle &v)
std::vector< SUMOReal > myVSafes
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.
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
The action is due to a TraCI request.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
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)
MSAbstractLaneChangeModel & getLaneChangeModel()
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
#define LCA_RIGHT_IMPATIENCE
std::pair< SUMOReal, int > Info
information regarding save velocity (unused) and state flags of the ego vehicle
A class responsible for exchanging messages between cars involved in lane-change interaction.
const std::string & getID() const
Returns the id.
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver's reaction time.
#define CUT_IN_LEFT_SPEED_THRESHOLD
SUMOReal mySpeedGainProbability
a value for tracking the probability that a change to the offset with the same sign is beneficial ...
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
#define LOOK_FORWARD_RIGHT
bool amBlockingFollowerPlusNB()
SUMOReal informLeader(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int blocked, int dir, const std::pair< MSVehicle *, SUMOReal > &neighLead, SUMOReal remainingSeconds)
SUMOReal _patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel &cfModel)
void saveBlockerLength(MSVehicle *blocker, int lcaCounter)
save space for vehicles which need to counter-lane-change
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) ...
std::string tryID(const MSVehicle *v)
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.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
virtual void saveBlockerLength(SUMOReal length)
reserve space at the end of the lane to avoid dead locks
#define HELP_DECEL_FACTOR
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 myKeepRightProbability
a value for tracking the probability of following the/"Rechtsfahrgebot" (never a positive value) ...
#define LOOK_AHEAD_SPEED_MEMORY
SUMOTime myLastLaneChangeOffset
information how long ago the vehicle has performed a lane-change
#define ROUNDABOUT_DIST_BONUS
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) ...
SUMOReal myLookAheadSpeed
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
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
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.
Representation of a lane in the micro simulation.
const MSCFModel & myCarFollowModel
The vehicle's car following model.
bool currentDistDisallows(SUMOReal dist, int laneOffset, SUMOReal lookForwardDist)
Interface for lane-change models.
int getBestLaneOffset() const
returns the current offset from the best lane
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.
const std::string & getID() const
Returns the name of the vehicle.
The action is due to the wish to be faster (tactical lc)