48 #ifdef CHECK_MEMORY_LEAKS 50 #endif // CHECK_MEMORY_LEAKS 62 #define DEBUG_COND false 88 for (std::vector<MSLane*>::const_iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
107 const bool haveChanged =
change();
114 ce->lane->releaseVehicles();
128 ce->firstBlocked = 0;
131 ce->lane->getVehiclesSecure();
169 ce->lane->swapAfterLaneChange(t);
170 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();
268 bool changingAllowed1 = (state1 &
LCA_BLOCKED) == 0;
270 if ((state1 &
LCA_RIGHT) != 0 && changingAllowed1) {
275 if ((state1 & LCA_RIGHT) != 0 && (state1 &
LCA_URGENT) != 0) {
276 (
myCandi - 1)->lastBlocked = vehicle;
277 if ((
myCandi - 1)->firstBlocked == 0) {
278 (
myCandi - 1)->firstBlocked = vehicle;
289 bool changingAllowed2 = (state2 &
LCA_BLOCKED) == 0;
291 if ((state2 &
LCA_LEFT) != 0 && changingAllowed2) {
296 if ((state2 & LCA_LEFT) != 0 && (state2 &
LCA_URGENT) != 0) {
297 (
myCandi + 1)->lastBlocked = vehicle;
298 if ((
myCandi + 1)->firstBlocked == 0) {
299 (
myCandi + 1)->firstBlocked = vehicle;
327 if (target->hoppedVeh != 0) {
328 SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
347 MSLane::VehCont::iterator i = find(target->lane->myTmpVehicles.begin(), target->lane->myTmpVehicles.end(), prohibitor);
348 if (i != target->lane->myTmpVehicles.end()) {
349 assert(*i == prohibitor);
350 target->lane->myTmpVehicles.erase(i);
355 target->lead = vehicle;
388 to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
390 to->hoppedVeh = vehicle;
406 MSLane* target = to->lane;
409 to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle);
411 to->hoppedVeh = vehicle;
414 from->lane->myTmpVehicles.insert(from->lane->myTmpVehicles.begin(), vehicle);
416 from->hoppedVeh = vehicle;
426 shadow->hoppedVeh = vehicle;
430 #ifdef DEBUG_CONTINUE_CHANGE 433 <<
" continueChange veh=" << vehicle->
getID()
435 <<
" dir=" << direction
436 <<
" pastMidpoint=" << pastMidpoint
448 std::pair<MSVehicle* const, SUMOReal>
458 if (target->hoppedVeh != 0) {
459 SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
461 neighLead = target->hoppedVeh;
465 if (neighLead == 0) {
466 MSLane* targetLane = target->lane;
476 return std::pair<MSVehicle* const, SUMOReal>(
static_cast<MSVehicle*
>(0), -1);
480 return target->lane->getLeaderOnConsecutive(dist, seen, speed, *
veh(
myCandi), bestLaneConts);
488 std::pair<MSVehicle* const, SUMOReal>
495 neighFollow =
getCloserFollower(candiPos, neighFollow, target->lane->getPartialBehind(candi));
496 if (neighFollow == 0) {
497 return target->lane->getFollowerOnConsecutive(
502 return std::pair<MSVehicle* const, SUMOReal>(neighFollow,
526 const std::pair<MSVehicle* const, SUMOReal>& leader,
527 const std::vector<MSVehicle::LaneQ>& preb)
const {
531 if (neighLead.first != 0 && neighLead.first == neighFollow.first) {
534 neighFollow.first = 0;
537 return checkChange(laneOffset, target->lane, leader, neighLead, neighFollow, preb);
544 const std::pair<MSVehicle* const, SUMOReal>& leader,
545 const std::pair<MSVehicle* const, SUMOReal>& neighLead,
546 const std::pair<MSVehicle* const, SUMOReal>& neighFollow,
547 const std::vector<MSVehicle::LaneQ>& preb)
const {
554 if (neighFollow.first != 0 && neighFollow.second < 0) {
557 if (neighLead.first != 0 && neighLead.second < 0) {
561 if ((blocked & blockedByFollower) == 0 && neighFollow.first != 0) {
564 blocked |= blockedByFollower;
569 if ((blocked & blockedByLeader) == 0 && neighLead.first != 0) {
572 blocked |= blockedByLeader;
578 laneOffset, msg, blocked, leader, neighLead, neighFollow, *targetLane, preb, &(
myCandi->lastBlocked), &(
myCandi->firstBlocked));
587 std::pair<MSVehicle* const, SUMOReal> neighLead2 = targetLane->
getCriticalLeader(dist, seen, speed, *vehicle);
588 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
590 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
591 state |= blockedByLeader;
595 if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
598 state |= blockedByLeader;
615 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
616 while (!nextLane->
isLinkEnd(link) && seen <= space2change) {
620 || (nextLane->
getEdge().
isInternal() && (*link)->getViaLaneOrLane()->getEdge().isInternal())
625 #ifdef HAVE_INTERNAL_LANES 626 if ((*link)->getViaLane() == 0) {
632 nextLane = (*link)->getViaLaneOrLane();
637 if (nextLane->
isLinkEnd(link) && seen < space2change) {
638 #ifdef DEBUG_CHECK_CHANGE 640 std::cout <<
SIMTIME <<
" checkChange insufficientSpace: seen=" << seen <<
" space2change=" << space2change <<
"\n";
646 if ((state & LCA_BLOCKED) == 0) {
654 MSLinkCont::const_iterator link =
MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
655 while (!nextLane->
isLinkEnd(link) && seen <= space2change && seen <= dist) {
656 nextLane = (*link)->getViaLaneOrLane();
658 if (targetLane == 0) {
662 std::pair<MSVehicle* const, SUMOReal> neighLead2 = targetLane->
getLeader(vehicle, -seen, std::vector<MSLane*>());
663 if (neighLead2.first != 0 && neighLead2.first != neighLead.first
665 vehicle->
getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
666 state |= blockedByLeader;
670 #ifdef HAVE_INTERNAL_LANES 671 if ((*link)->getViaLane() == 0) {
684 #ifdef DEBUG_CHECK_CHANGE 685 const int oldstate = state;
690 #ifdef DEBUG_CHECK_CHANGE 693 <<
" veh=" << vehicle->
getID()
719 if (!isOpposite && leader.first == 0) {
735 std::pair<MSVehicle*, SUMOReal> neighLead((
MSVehicle*)0, -1);
739 assert(leader.first != 0);
744 std::pair<MSVehicle*, SUMOReal> columnLeader = leader;
746 bool foundSpaceAhead =
false;
747 SUMOReal seen = leader.second + leader.first->getVehicleType().getLengthWithGap();
749 while (!foundSpaceAhead) {
750 const SUMOReal requiredSpaceAfterLeader = (columnLeader.first->getCarFollowModel().getSecureGap(
755 std::pair<MSVehicle* const, SUMOReal> leadLead = columnLeader.first->getLane()->getLeader(
756 columnLeader.first, columnLeader.first->getPositionOnLane(), conts, requiredSpaceAfterLeader + mergeBrakeGap,
true);
758 #ifdef DEBUG_CHANGE_OPPOSITE 760 std::cout <<
" leadLead=" <<
Named::getIDSecure(leadLead.first) <<
" gap=" << leadLead.second <<
"\n";
763 if (leadLead.first == 0) {
764 foundSpaceAhead =
true;
766 const SUMOReal requiredSpace = (requiredSpaceAfterLeader
767 + vehicle->
getCarFollowModel().
getSecureGap(overtakingSpeed, leadLead.first->getSpeed(), leadLead.first->getCarFollowModel().getMaxDecel()));
768 if (leadLead.second > requiredSpace) {
769 foundSpaceAhead =
true;
771 #ifdef DEBUG_CHANGE_OPPOSITE 773 std::cout <<
" not enough space after columnLeader=" << leadLead.first->getID() <<
" gap=" << leadLead.second <<
" required=" << requiredSpace <<
"\n";
776 seen += leadLead.second + leadLead.first->getVehicleType().getLengthWithGap();
777 if (seen > maxLookAhead) {
778 #ifdef DEBUG_CHANGE_OPPOSITE 780 std::cout <<
" cannot changeOpposite due to insufficient free space after columnLeader (seen=" << seen <<
" columnLeader=" << leadLead.first->getID() <<
")\n";
786 egoGap += columnLeader.first->getVehicleType().getLengthWithGap() + leadLead.second;
787 columnLeader = leadLead;
788 #ifdef DEBUG_CHANGE_OPPOSITE 790 std::cout <<
" new columnLeader=" << columnLeader.first->getID() <<
"\n";
796 #ifdef DEBUG_CHANGE_OPPOSITE 798 std::cout <<
" compute time/space to overtake for columnLeader=" << columnLeader.first->getID() <<
" gap=" << columnLeader.second <<
"\n";
806 #ifdef DEBUG_CHANGE_OPPOSITE 808 std::cout <<
" cannot changeOpposite due to upcoming stop (dist=" << vehicle->
nextStopDist() <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
815 #ifdef DEBUG_CHANGE_OPPOSITE 818 <<
" veh=" << vehicle->
getID()
819 <<
" changeOpposite opposite=" << opposite->
getID()
822 <<
" timeToOvertake=" << timeToOvertake
823 <<
" spaceToOvertake=" << spaceToOvertake
830 const MSVehicle* oncoming = neighLead.first;
833 #ifdef DEBUG_CHANGE_OPPOSITE 836 <<
" timeToOvertake=" << timeToOvertake
837 <<
" spaceToOvertake=" << spaceToOvertake
838 <<
" oncomingGap=" << neighLead.second
839 <<
" leaderGap=" << leader.second
843 if (neighLead.second - spaceToOvertake - timeToOvertake * oncoming->
getSpeed() < 0) {
845 #ifdef DEBUG_CHANGE_OPPOSITE 847 std::cout <<
" cannot changeOpposite due to dangerous oncoming\n";
857 assert(bestLaneConts.size() >= 1);
858 std::vector<MSLane*>::const_iterator it = bestLaneConts.begin() + 1;
859 while (seen < spaceToOvertake && it != bestLaneConts.end()) {
860 if ((*it)->getOpposite() == 0) {
864 if (*(it - 1) != 0) {
870 seen += (*it)->getLength();
872 if (seen < spaceToOvertake) {
873 #ifdef DEBUG_CHANGE_OPPOSITE 875 std::cout <<
" cannot changeOpposite due to insufficient space (seen=" << seen <<
" spaceToOvertake=" << spaceToOvertake <<
")\n";
880 #ifdef DEBUG_CHANGE_OPPOSITE 882 std::cout <<
" seen=" << seen <<
" spaceToOvertake=" << spaceToOvertake <<
" timeToOvertake=" << timeToOvertake <<
"\n";
893 std::vector<MSVehicle::LaneQ> preb = vehicle->
getBestLanes();
894 if (isOpposite && leader.first != 0) {
900 std::pair<MSVehicle* const, SUMOReal> neighFollow = opposite->
getOppositeFollower(vehicle);
901 int state =
checkChange(direction, opposite, leader, neighLead, neighFollow, preb);
912 #ifdef DEBUG_CHANGE_OPPOSITE 914 std::cout <<
SIMTIME <<
" changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction <<
" opposite=" <<
Named::getIDSecure(opposite) <<
" state=" << state <<
"\n";
919 #ifdef DEBUG_CHANGE_OPPOSITE 921 std::cout <<
SIMTIME <<
" not changing to opposite veh=" << vehicle->
getID() <<
" dir=" << direction <<
" opposite=" <<
Named::getIDSecure(opposite) <<
" state=" << state <<
"\n";
943 SUMOReal t = (u - v - sqrt(4 * (u - v) * (u - v) + 8 * a * g) * sign * 0.5) / a;
947 const SUMOReal timeToMaxSpeed = (vMax - v) / a;
949 if (t <= timeToMaxSpeed) {
951 spaceToOvertake = v * t + t * t * a * 0.5;
955 const SUMOReal s = v * timeToMaxSpeed + timeToMaxSpeed * timeToMaxSpeed * a * 0.5;
959 t = (g - s + m * vMax) / (vMax - u);
961 spaceToOvertake = s + (t - m) * vMax;
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.
MSEdge & getEdge() const
Returns the lane's edge.
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)
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, SUMOReal > getRealLeader(const ChangerIt &target) const
std::pair< MSVehicle *const, SUMOReal > getOppositeFollower(const MSVehicle *ego) const
SUMOReal getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
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 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...
void initChanger()
Initialize the changer before looping over all vehicles.
SUMOReal getLength() const
Returns the lane's length.
int checkChangeWithinEdge(int laneOffset, const std::pair< MSVehicle *const, SUMOReal > &leader, const std::vector< MSVehicle::LaneQ > &preb) const
bool mayChange(int direction) const
whether changing to the lane in the given direction should be considered
int getShadowDirection() const
return the direction in which the current shadow lane lies
SUMOReal getLength() const
Get vehicle's length [m].
const bool myChangeToOpposite
whether this edge allows changing to the opposite direction edge
virtual 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...
SUMOReal getWidth() const
Returns the lane's width.
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
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 startChange(MSVehicle *vehicle, ChangerIt &from, int direction)
start the lane change maneuver (and finish it instantly if gLaneChangeDuration == 0) ...
SUMOReal getPositionOnLane() const
Get the vehicle's position along the lane.
std::pair< MSVehicle *const, SUMOReal > getCriticalLeader(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh) const
Returns the most dangerous leader and the distance to him.
ChangeElem(MSLane *_lane)
VehCont myPartialVehicles
The lane's partial vehicles. This container holds all vehicles that are partially on this lane but wh...
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
static void computeOvertakingTime(const MSVehicle *vehicle, const MSVehicle *leader, SUMOReal gap, SUMOReal &timeToOvertake, SUMOReal &spaceToOvertake)
Compute the time and space required for overtaking the given leader.
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.
static MSVehicle * getCloserFollower(const SUMOReal maxPos, MSVehicle *follow1, MSVehicle *follow2)
return the closer follower of ego
MSAbstractLaneChangeModel & getLaneChangeModel()
std::string gDebugSelectedVehicle
SUMOReal getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
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)
std::pair< MSVehicle *const, SUMOReal > getRealFollower(const ChangerIt &target) const
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver's reaction time.
SUMOReal computeAngle() const
compute the current vehicle angle
virtual void updateChanger(bool vehHasChanged)
The action is urgent (to be defined by lc-model)
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle's current lane and their successors...
SUMOReal getLateralSpeed() const
return the lateral speed of the current lane change maneuver
SUMOReal myAngle
the angle (
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
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.
virtual bool changeOpposite(std::pair< MSVehicle *, SUMOReal > leader)
bool isStopped() const
Returns whether the vehicle is at a stop.
The link is a (hard) right direction.
virtual void setOwnState(int state)
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].
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
MSLaneChanger()
Default constructor.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
int checkChange(int laneOffset, const MSLane *targetLane, const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &neighLead, const std::pair< MSVehicle *const, SUMOReal > &neighFollow, const std::vector< MSVehicle::LaneQ > &preb) const
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.
std::vector< MSVehicle * > VehCont
Container for vehicles.
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
bool startLaneChangeManeuver(MSLane *source, MSLane *target, int direction)
start the lane change maneuver and return whether it continues
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos, MSMoveReminder::Notification notification, SUMOReal posLat=0)
Inserts the given vehicle at the given position.
SUMOReal getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
void primaryLaneChanged(MSLane *source, MSLane *target, int direction)
called once when the vehicles primary lane changes
LaneChangeAction
The state of a vehicle's lane-change behavior.
bool havePriority() const
Returns whether this link is a major link.
bool myAllowsSwap
Whether blocking vehicles may be swapped.
std::pair< MSVehicle *const, SUMOReal > getOppositeLeader(const MSVehicle *ego, SUMOReal dist) const
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.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Changer::iterator ChangerIt
the iterator moving over the ChangeElems
SUMOReal getSpeed() const
Returns the vehicle's current speed.
SUMOReal myPos
the stored position
SUMOReal getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
SUMOReal nextStopDist() const
return the distance to the next stop or SUMORealMax if there is none.
Changer myChanger
Container for ChangeElemements, one for every lane in the edge.
SUMOReal getOppositePos(SUMOReal pos) const
return the corresponding position on the opposite lane
LinkState getState() const
Returns the current state of the link.
void registerUnchanged(MSVehicle *vehicle)
SUMOReal myPosLat
the stored lateral position
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
SUMOReal myBackPos
the stored back position
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
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...
static SUMOTime gLaneChangeDuration
Representation of a lane in the micro simulation.
The vehicle is blocked by right follower.
Interface for lane-change models.
std::pair< MSVehicle *const, SUMOReal > getLeader(const MSVehicle *veh, const SUMOReal vehPos, const std::vector< MSLane * > &bestLaneConts, SUMOReal dist=-1, bool checkTmpVehicles=false) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
static const Position INVALID
The vehicle is blocked by left leader.
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
const std::string & getID() const
Returns the name of the vehicle.
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)