37 #define LOOK_FORWARD_SPEED_DIVIDER 14.
39 #define LOOK_FORWARD_FAR 15.
40 #define LOOK_FORWARD_NEAR 5.
45 #define JAM_FACTOR2 1.
53 myChangeProbability(0),
54 myLeadingBlockerLength(0), myLeftSpace(0) {}
64 const std::pair<MSVehicle*, double>& leader,
65 const std::pair<MSVehicle*, double>& neighLead,
66 const std::pair<MSVehicle*, double>& neighFollow,
68 const std::vector<MSVehicle::LaneQ>& preb,
72 return (laneOffset == -1 ?
73 wantsChangeToRight(msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked)
74 :
wantsChangeToLeft(msgPass, blocked, leader, neighLead, neighFollow, neighLane, preb, lastBlocked, firstBlocked));
82 const std::pair<MSVehicle*, double>& leader,
83 const std::pair<MSVehicle*, double>& neighLead,
84 const std::pair<MSVehicle*, double>& neighFollow,
86 const std::vector<MSVehicle::LaneQ>& preb,
91 int bestLaneOffset = 0;
92 double currentDist = 0;
94 double neighExtDist = 0;
95 double currExtDist = 0;
102 for (
int p = 0; p < (int) preb.size(); ++p) {
103 if (preb[p].lane == prebLane && p > 0) {
106 currentDist = curr.
length;
108 neighDist = preb[p - 1].length;
109 neighExtDist = preb[p - 1].lane->getLength();
110 best = preb[p + bestLaneOffset];
119 if (leader.first != 0
136 if ((*lastBlocked) !=
nullptr) {
146 (*lastBlocked) =
nullptr;
172 if (neighLead.second > 0 && neighLead.second > leader.second) {
178 if (neighLead.first != 0 && (neighLead.first->getLaneChangeModel().getOwnState()&
LCA_LEFT) != 0) {
196 double maxJam =
MAX2(preb[currIdx - 1].occupation, preb[currIdx].occupation);
209 if (currExtDist > neighExtDist && (neighLeftPlace * 2. < rv)) {
225 (
currentDistAllows(neighDist, bestLaneOffset, rv) || neighDist >= currentDist)) {
245 if (neighLead.first == 0) {
251 if (leader.first == 0) {
260 if (thisLaneVSafe - neighLaneVSafe > 5. / 3.6) {
272 vmax -= (double)(5. / 2.6);
273 if (neighLaneVSafe >= vmax) {
289 const std::pair<MSVehicle*, double>& leader,
290 const std::pair<MSVehicle*, double>& neighLead,
291 const std::pair<MSVehicle*, double>& neighFollow,
293 const std::vector<MSVehicle::LaneQ>& preb,
298 int bestLaneOffset = 0;
299 double currentDist = 0;
300 double neighDist = 0;
301 double neighExtDist = 0;
302 double currExtDist = 0;
309 for (
int p = 0; p < (int) preb.size(); ++p) {
310 if (preb[p].lane == prebLane) {
313 currentDist = curr.
length;
315 neighDist = preb[p + 1].length;
316 neighExtDist = preb[p + 1].lane->getLength();
317 best = preb[p + bestLaneOffset];
326 if (leader.first != 0
343 if ((*lastBlocked) !=
nullptr) {
353 (*lastBlocked) =
nullptr;
379 if (neighLead.second > 0 && neighLead.second > leader.second) {
385 if (neighLead.first != 0 && (neighLead.first->getLaneChangeModel().getOwnState()&
LCA_RIGHT) != 0) {
403 double maxJam =
MAX2(preb[currIdx + 1].occupation, preb[currIdx].occupation);
416 if (currExtDist > neighExtDist && (neighLeftPlace * 2. < lv)) {
441 (
currentDistAllows(neighDist, bestLaneOffset, lv) || neighDist >= currentDist)) {
459 if (neighLead.first == 0) {
465 if (leader.first == 0) {
473 if (thisLaneVSafe > neighLaneVSafe) {
496 double MAGIC_offset = 1.;
506 return MAX2(min, safe);
518 double nVSafe = wanted;
520 for (std::vector<double>::const_iterator i =
myVSafes.begin(); i !=
myVSafes.end(); ++i) {
522 if (v >= min && v <= max) {
523 nVSafe =
MIN2(v, nVSafe);
538 return (min + wanted) / (double) 2.0;
541 return (max + wanted) / (double) 2.0;
543 return (min + wanted) / (double) 2.0;
554 return (min + wanted) / (double) 2.0;
567 return (max + wanted) / (double) 2.0;
573 return (min + wanted) / (double) 2.0;
604 const std::pair<MSVehicle*, double>& neighLead,
605 const std::pair<MSVehicle*, double>& neighFollow) {
607 assert(neighFollow.first != 0);
623 if (neighLead.first != 0 && neighLead.second > 0) {
#define LOOK_FORWARD_NEAR
#define LOOK_FORWARD_SPEED_DIVIDER
@ LCA_BLOCKED
blocked in all directions
@ LCA_URGENT
The action is urgent (to be defined by lc-model)
@ LCA_STAY
Needs to stay on the current lane.
@ LCA_BLOCKED_BY_LEADER
blocked by leader
@ LCA_AMBLOCKINGFOLLOWER_DONTBRAKE
@ LCA_COOPERATIVE
The action is done to help someone else.
@ LCA_LEFT
Wants go to the left.
@ LCA_STRATEGIC
The action is needed to follow the route (navigational lc)
@ LCA_AMBACKBLOCKER_STANDING
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
@ LCA_WANTS_LANECHANGE
lane can change
@ LCA_RIGHT
Wants go to the right.
@ LCA_BLOCKED_BY_FOLLOWER
blocker by follower
#define UNUSED_PARAMETER(x)
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
A class responsible for exchanging messages between cars involved in lane-change interaction.
void * informNeighFollower(void *info, MSVehicle *sender)
Informs the follower on the desired lane.
void * informNeighLeader(void *info, MSVehicle *sender)
Informs the leader on the desired lane.
Interface for lane-change models.
int myOwnState
The current state of the vehicle.
virtual bool predInteraction(const std::pair< MSVehicle *, double > &leader)
virtual void prepareStep()
const MSCFModel & myCarFollowModel
The vehicle's car following model.
MSVehicle & myVehicle
The vehicle this lane-changer belongs to.
virtual bool congested(const MSVehicle *const neighLeader)
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
The car-following model abstraction.
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
virtual double getSecureGap(const MSVehicle *const, const MSVehicle *const, 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 double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle's follow speed (no dawdling)
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
bool isInternal() const
return whether this edge is an internal edge
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...
std::vector< double > myVSafes
std::pair< double, int > Info
MSLCM_DK2008(MSVehicle &v)
bool amBlockingFollowerPlusNB()
virtual int wantsChangeToRight(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 to right This method gets the information about...
double myChangeProbability
void informBlocker(MSAbstractLaneChangeModel::MSLCMessager &msgPass, int &blocked, int dir, const std::pair< MSVehicle *, double > &neighLead, const std::pair< MSVehicle *, double > &neighFollow)
bool currentDistAllows(double dist, int laneOffset, double lookForwardDist)
double myLeadingBlockerLength
virtual void * inform(void *info, MSVehicle *sender)
virtual void prepareStep()
virtual int wantsChangeToLeft(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 to left This method gets the information about ...
virtual double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)
Called to adapt the speed in order to allow a lane change.
bool currentDistDisallows(double dist, int laneOffset, double lookForwardDist)
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
double getLength() const
Returns the lane's length.
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
MSEdge & getEdge() const
Returns the lane's edge.
Representation of a vehicle in the micro simulation.
double getSpeed() const
Returns the vehicle's current speed.
double getPositionOnLane() const
Get the vehicle's position along the lane.
const MSLane * getLane() const
Returns the lane the vehicle is on.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
double getMinGap() const
Get the free space in front of vehicles of this class.
A structure representing the best lanes for continuing the current route starting at 'lane'.
double length
The overall length which may be driven when using this lane without a lane change.
MSLane * lane
The described lane.
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive.
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.