47 #ifdef CHECK_MEMORY_LEAKS 49 #endif // CHECK_MEMORY_LEAKS 63 #define ZIPPER_ADAPT_TIME 10 68 #ifndef HAVE_INTERNAL_LANES 71 myLaneBefore(predLane),
81 myKeepClear(keepClear),
89 myLaneBefore(predLane),
99 myKeepClear(keepClear),
101 myInternalLaneBefore(0),
115 const std::vector<MSLink*>& foeLinks,
116 const std::vector<MSLane*>& foeLanes,
117 MSLane* internalLaneBefore) {
122 for (std::vector<MSLane*>::const_iterator it_lane = foeLanes.begin(); it_lane != foeLanes.end(); ++it_lane) {
127 #ifdef HAVE_INTERNAL_LANES 128 myInternalLaneBefore = internalLaneBefore;
130 if (internalLaneBefore != 0) {
132 lane = internalLaneBefore;
138 #ifdef MSLink_DEBUG_CROSSING_POINTS 142 const bool beforeInternalJunction = lane->
getLinkCont()[0]->getViaLaneOrLane()->getEdge().isInternal();
145 for (std::vector<const MSLane*>::const_iterator it_lane =
myFoeLanes.begin(); it_lane !=
myFoeLanes.end(); ++it_lane) {
147 if (sameTarget && !beforeInternalJunction) {
150 myLengthsBehindCrossing.push_back(std::make_pair(0, 0));
151 #ifdef MSLink_DEBUG_CROSSING_POINTS 153 <<
" " << lane->
getID()
154 <<
" merges with " << (*it_lane)->getID()
155 <<
" nextLane " << lane->
getLinkCont()[0]->getViaLaneOrLane()->getID()
156 <<
" dist1=" << myLengthsBehindCrossing.back().first
157 <<
" dist2=" << myLengthsBehindCrossing.back().second
162 #ifdef MSLink_DEBUG_CROSSING_POINTS 165 bool haveIntersection =
true;
166 if (intersections1.size() == 0) {
167 intersections1.push_back(-10000.0);
168 haveIntersection =
false;
169 }
else if (intersections1.size() > 1) {
170 std::sort(intersections1.begin(), intersections1.end());
172 std::vector<SUMOReal> intersections2 = (*it_lane)->getShape().intersectsAtLengths2D(lane->
getShape());
173 #ifdef MSLink_DEBUG_CROSSING_POINTS 176 if (intersections2.size() == 0) {
177 intersections2.push_back(0);
178 }
else if (intersections2.size() > 1) {
179 std::sort(intersections2.begin(), intersections2.end());
181 if (haveIntersection) {
183 intersections1.back() -= (*it_lane)->getWidth() / 2;
184 intersections2.back() -= lane->
getWidth() / 2;
187 intersections2.back() = (*it_lane)->interpolateGeometryPosToLanePos(intersections2.back());
192 intersections1.back() = 0;
196 myLengthsBehindCrossing.push_back(std::make_pair(
197 lane->
getLength() - intersections1.back(),
198 (*it_lane)->getLength() - intersections2.back()));
200 #ifdef MSLink_DEBUG_CROSSING_POINTS 202 <<
" intersection of " << lane->
getID()
204 <<
" with " << (*it_lane)->getID()
205 <<
" totalLength=" << (*it_lane)->getLength()
206 <<
" dist1=" << myLengthsBehindCrossing.back().first
207 <<
" dist2=" << myLengthsBehindCrossing.back().second
217 for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
218 const MSLane* sibling = (*it)->getViaLane();
219 if (sibling != lane && sibling != 0) {
221 #ifdef MSLink_DEBUG_CROSSING_POINTS 224 if (intersections1.size() > 0) {
225 std::sort(intersections1.begin(), intersections1.end());
228 myLengthsBehindCrossing.push_back(std::make_pair(
229 lane->
getLength() - intersections1.back(),
230 sibling->
getLength() - intersections1.back()));
232 #ifdef MSLink_DEBUG_CROSSING_POINTS 233 std::cout <<
" adding same-origin foe" << sibling->
getID()
234 <<
" dist1=" << myLengthsBehindCrossing.back().first
235 <<
" dist2=" << myLengthsBehindCrossing.back().second
250 for (MSLinkCont::const_iterator it = predLinks.begin(); it != predLinks.end(); ++it) {
251 const MSEdge* target = &((*it)->getLane()->getEdge());
252 if (*it !=
this && target == myTarget) {
260 std::pair<SUMOReal, SUMOReal>
269 arrivalTimeBraking, arrivalSpeedBraking, waitingTime, dist)));
283 if ((*i)->isBlockingAnyone()) {
299 std::map<const SUMOVehicle*, ApproachingVehicleInformation>::const_iterator i =
myApproachingVehicles.find(veh);
318 std::vector<const SUMOVehicle*>* collectFoes)
const {
329 const MSLink* foeLink = *it;
338 && (arrivalTime > i->second.arrivalTime
342 if (
blockedByFoe(i->first, i->second, arrivalTime, leaveTime, arrivalSpeed, leaveSpeed,
false,
343 impatience, decel, waitingTime)) {
345 if (collectFoes == 0) {
349 collectFoes->push_back(i->first);
360 return collectFoes == 0 || collectFoes->size() == 0;
367 if ((*i)->haveRed()) {
371 if ((*i)->blockedAtTime(arrivalTime, leaveTime, arrivalSpeed, leaveSpeed,
myLane == (*i)->getLane(),
372 impatience, decel, waitingTime, collectFoes)) {
376 if (collectFoes != 0 && collectFoes->size() > 0) {
386 std::vector<const SUMOVehicle*>* collectFoes)
const {
388 if (
blockedByFoe(i->first, i->second, arrivalTime, leaveTime, arrivalSpeed, leaveSpeed, sameTargetLane,
389 impatience, decel, waitingTime)) {
390 if (collectFoes == 0) {
393 collectFoes->push_back(i->first);
408 assert(waitingTime > 0);
420 if (sameTargetLane && (arrivalTime - avi.
leavingTime < lookAhead
425 }
else if (foeArrivalTime > leaveTime) {
427 if (sameTargetLane && (foeArrivalTime - leaveTime < lookAhead
448 assert(distLeft > 0);
459 if ((*i)->blockedAtTime(arrivalTime, leaveTime, speed, speed,
myLane == (*i)->getLane(), 0, decel, 0)) {
463 for (std::vector<const MSLane*>::const_iterator i =
myFoeLanes.begin(); i !=
myFoeLanes.end(); ++i) {
464 if ((*i)->getVehicleNumberWithPartials() > 0) {
495 #ifdef HAVE_INTERNAL_LANES 496 if (myInternalLane != 0) {
497 approachedLane = myInternalLane;
504 const std::vector<MSLane::IncomingLaneInfo> possibleLanes = approachedLane->
getIncomingLanes();
505 std::vector<MSLane::IncomingLaneInfo>::const_iterator i;
506 for (i = possibleLanes.begin(); i != possibleLanes.end(); i++) {
509 for (MSLinkCont::const_iterator j = outgoingLinks.begin(); j != outgoingLinks.end(); j++) {
522 #ifdef HAVE_INTERNAL_LANES 523 if (myInternalLane == 0 ||
myAmCont) {
533 assert(predLink != 0);
548 #ifdef HAVE_INTERNAL_LANES 549 const std::string via = getViaLane() == 0 ?
"" : getViaLane()->getID();
551 const std::string via =
"";
555 std::vector<std::pair<SUMOTime, const SUMOVehicle*> > toSort;
557 toSort.push_back(std::make_pair(it->second.arrivalTime, it->first));
559 std::sort(toSort.begin(), toSort.end());
560 for (std::vector<std::pair<SUMOTime, const SUMOVehicle*> >::const_iterator it = toSort.begin(); it != toSort.end(); ++it) {
579 #ifdef HAVE_INTERNAL_LANES 581 MSLink::getViaLane()
const {
582 return myInternalLane;
604 MSLink::getLeaderInfo(
SUMOReal dist,
SUMOReal minGap, std::vector<const MSPerson*>* collectBlockers)
const {
611 for (
int i = 0; i < (int)
myFoeLanes.size(); ++i) {
614 const SUMOReal distToCrossing = dist - myLengthsBehindCrossing[i].first;
616 const bool sameSource = (myInternalLaneBefore != 0 && myInternalLaneBefore->getLogicalPredecessorLane() == foeLane->
getLogicalPredecessorLane());
617 const SUMOReal crossingWidth = (sameTarget || sameSource) ? 0 : foeLane->
getWidth();
618 const SUMOReal foeCrossingWidth = (sameTarget || sameSource) ? 0 : myInternalLaneBefore->getWidth();
620 std::cout <<
" distToCrossing=" << distToCrossing <<
" foeLane=" << foeLane->
getID() <<
"\n";
622 if (distToCrossing + crossingWidth < 0) {
625 const SUMOReal foeDistToCrossing = foeLane->
getLength() - myLengthsBehindCrossing[i].second;
633 const bool cannotIgnore = contLane || sameTarget || sameSource;
637 if (!cannotIgnore && !foeLane->
getLinkCont()[0]->getApproaching(leader).willPass && leader->
isFrontOnLane(foeLane)) {
644 if (contLane && !sameSource) {
648 const SUMOReal leaderBackDist = foeDistToCrossing - leaderBack;
650 std::cout <<
" distToCrossing=" << distToCrossing <<
" leader back=" << leaderBack <<
" backDist=" << leaderBackDist <<
"\n";
652 if (leaderBackDist + foeCrossingWidth < 0) {
657 gap = distToCrossing - leaderBackDist - (sameTarget ? minGap : 0);
660 std::cout <<
" leader=" << leader->
getID() <<
" contLane=" << contLane <<
" cannotIgnore=" << cannotIgnore <<
"\n";
664 const bool stopAsap = leader->
isFrontOnLane(foeLane) ? cannotIgnore : sameTarget;
665 result.push_back(
LinkLeader(leader, gap, stopAsap ? -1 : distToCrossing));
671 if (distToPeds >= -MSPModel::SAFETY_GAP &&
MSPModel::getModel()->blockedAtDist(foeLane, foeDistToCrossing, collectBlockers)) {
683 #ifdef HAVE_INTERNAL_LANES 684 if (myInternalLane != 0) {
685 return myInternalLane;
694 #ifdef HAVE_INTERNAL_LANES 696 if (myInternalLaneBefore != 0) {
708 if (direction == -1) {
710 }
else if (direction == 1) {
723 if (before != 0 && after != 0) {
750 #ifdef HAVE_INTERNAL_LANES 751 return myInternalLaneBefore;
761 std::vector<const SUMOVehicle*>* collectFoes)
const {
768 throw ProcessError(
"Zipper junctions with more than two conflicting lanes are not supported (at junction '" 787 for (std::vector<const SUMOVehicle*>::const_iterator i = collectFoes->begin(); i != collectFoes->end(); ++i) {
812 const SUMOReal followInTime = vSafeOrig + (follow - vSafeOrig) /
MAX2((
SUMOReal)1, secondsToArrival /
TS);
813 vSafe =
MIN2(vSafe, followInTime);
834 followDist > leaderDist &&
bool gDebugFlag1
global utility flags for debugging
SUMOReal getZipperSpeed(const MSVehicle *ego, const SUMOReal dist, SUMOReal vSafe, SUMOTime arrivalTime, std::vector< const SUMOVehicle * > *collectFoes) const
return the speed at which ego vehicle must approach the zipper link
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
MSEdge & getEdge() const
Returns the lane's edge.
int myIndex
The position within this respond.
Representation of a vehicle in the micro simulation.
bool hasFoes() const
Returns whether this link belongs to a junction where more than one edge is incoming.
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
bool hasApproachingFoe(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal speed, SUMOReal decel) const
Returns the information whether a vehicle is approaching on one of the link's foe streams...
static const SUMOReal SAFETY_GAP
const MSLane * getInternalLaneBefore() const
return myInternalLaneBefore (always 0 when compiled without internal lanes)
MSLane * myLane
The lane behind the junction approached by this link.
void addBlockedLink(MSLink *link)
ApproachingVehicleInformation getApproaching(const SUMOVehicle *veh) const
LinkState myState
The state of the link.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
std::pair< SUMOReal, SUMOReal > getLastIntersections(const MSLane *lane, const MSLane *foe)
MSLink * getParallelLink(int direction) const
return the link that is parallel to this lane or 0
void setRequestInformation(int index, bool hasFoes, bool isCont, const std::vector< MSLink * > &foeLinks, const std::vector< MSLane * > &foeLanes, MSLane *internalLaneBefore=0)
Sets the request information.
void setApproaching(const SUMOVehicle *approaching, const SUMOTime arrivalTime, const SUMOReal arrivalSpeed, const SUMOReal leaveSpeed, const bool setRequest, const SUMOTime arrivalTimeBraking, const SUMOReal arrivalSpeedBraking, const SUMOTime waitingTime, SUMOReal dist)
Sets the information about an approaching vehicle.
const std::map< const SUMOVehicle *, ApproachingVehicleInformation > & getApproaching() const
return all approaching vehicles
static const SUMOReal ZIPPER_ADAPT_DIST
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
bool myHasFoes
Whether any foe links exist.
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)
This is an uncontrolled, minor link, has to stop.
SUMOReal getLength() const
Returns the lane's length.
The base class for an intersection.
std::vector< MSLink * > mySublaneFoeLinks
SUMOTime myLastStateChange
The time of the last state change.
std::vector< MSLink * > myFoeLinks
#define ZIPPER_ADAPT_TIME
void setTLState(LinkState state, SUMOTime t)
Sets the current tl-state.
std::string time2string(SUMOTime t)
SUMOReal getLength() const
Get vehicle's length [m].
static bool couldBrakeForLeader(SUMOReal followDist, SUMOReal leaderDist, const MSVehicle *follow, const MSVehicle *leader)
whether fllower could stay behind leader (possibly by braking)
LinkDirection myDirection
An abstract (hopefully human readable) definition of the link's direction.
SUMOReal getWidth() const
Returns the lane's width.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
static const SUMOTime myLookaheadTime
LinkDirection getDirection() const
Returns the direction the vehicle passing this link take.
std::map< const SUMOVehicle *, ApproachingVehicleInformation > myApproachingVehicles
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
bool lastWasContMajor() const
whether this is a link past an internal junction which currently has priority
This is an uncontrolled, all-way stop link.
bool fromInternalLane() const
return whether the fromLane of this link is an internal lane
#define UNUSED_PARAMETER(x)
This is an uncontrolled, zipper-merge link.
#define WRITE_WARNING(msg)
bool blockedAtTime(SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, bool sameTargetLane, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime, std::vector< const SUMOVehicle * > *collectFoes=0) const
Returns the information whether this link is blocked Valid after the vehicles have set their requests...
MSLink * computeParallelLink(int direction)
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)...
int getIndex() const
Returns the respond index (for visualization)
SUMOTime getLeaveTime(const SUMOTime arrivalTime, const SUMOReal arrivalSpeed, const SUMOReal leaveSpeed, const SUMOReal vehicleLength) const
return the expected time at which the given vehicle will clear the link
const std::string & getID() const
Returns the id.
A road/street connecting two junctions.
bool opened(SUMOTime arrivalTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, SUMOReal vehicleLength, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime, SUMOReal posLat=0, std::vector< const SUMOVehicle * > *collectFoes=0) const
Returns the information whether the link may be passed.
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
void passedJunction(const MSVehicle *vehicle)
erase vehicle from myLinkLeaders
Representation of a vehicle.
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
static MSPModel * getModel()
bool isInternalJunctionLink() const
return whether the fromLane and the toLane of this link are internal lanes
MSLane * getLane() const
Returns the connected lane.
static const SUMOTime myLookaheadTimeZipper
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
std::set< MSLink * > myBlockedFoeLinks
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
bool blockedByFoe(const SUMOVehicle *veh, const ApproachingVehicleInformation &avi, SUMOTime arrivalTime, SUMOTime leaveTime, SUMOReal arrivalSpeed, SUMOReal leaveSpeed, bool sameTargetLane, SUMOReal impatience, SUMOReal decel, SUMOTime waitingTime) const
bool isLeader(const MSVehicle *ego, const MSVehicle *foe)
std::vector< LinkLeader > LinkLeaders
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
SUMOReal getMaxDecel() const
Get the vehicle type's maximum deceleration [m/s^2].
void initParallelLinks()
initialize parallel links (to be called after all links are loaded)
virtual SUMOReal getLateralPositionOnLane() const =0
Get the vehicle's lateral position on the lane.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
int getIndex() const
Returns the lane's index.
bool isInternal() const
return whether this edge is an internal edge
static bool unsafeMergeSpeeds(SUMOReal leaderSpeed, SUMOReal followerSpeed, SUMOReal leaderDecel, SUMOReal followerDecel)
return whether the given vehicles may NOT merge safely
SUMOReal getLength() const
Returns the length of this link.
static bool maybeOccupied(MSLane *lane)
returns whether the given lane may still be occupied by a vehicle currently on it ...
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
MSLane * getApproachingLane() const
Returns the lane leading to this link.
bool havePriority() const
Returns whether this link is a major link.
bool willHaveBlockedFoe() 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...
The edge is a normal street.
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
MSLane * myLaneBefore
The lane approaching this link.
MSLink(MSLane *predLane, MSLane *succLane, LinkDirection dir, LinkState state, SUMOReal length, bool keepClear, MSTrafficLightLogic *logic, int tlLinkIdx)
Constructor for simulation not using internal lanes.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
static SUMOReal gLateralResolution
MSJunction * myJunction
the junction to which this link belongs
bool haveRed() const
Returns whether this link is blocked by a red (or redyellow) traffic light.
SUMOReal getSpeed() const
Returns the vehicle's current speed.
void writeApproaching(OutputDevice &od, const std::string fromLaneID) const
write information about all approaching vehicles to the given output device
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction ...
SUMOReal getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
static SUMOTime gIgnoreJunctionBlocker
Information whether the simulation regards internal lanes.
const PositionVector & getShape() const
Returns this lane's shape.
The parent class for traffic light logics.
Static storage of an output device and its base (abstract) implementation.
bool closeTag()
Closes the most recently opened tag.
const MSJunction * getFromJunction() const
void removeApproaching(const SUMOVehicle *veh)
removes the vehicle from myApproachingVehicles
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
MSLane * getLane() const
Returns the lane the vehicle is on.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
The edge is an internal edge.
SUMOReal interpolateGeometryPosToLanePos(SUMOReal geometryPos) const
std::vector< SUMOReal > intersectsAtLengths2D(const PositionVector &other) const
For all intersections between this vector and other, return the 2D-length of the subvector from this ...
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction ...
Representation of a lane in the micro simulation.
bool isLeader(const MSVehicle *ego, const MSVehicle *foe)
void passedJunction(const MSVehicle *vehicle)
erase vehicle from myLinkLeaders of this links junction
bool isExitLink() const
return whether the fromLane of this link is an internal lane and toLane is a normal lane ...
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
std::vector< const MSLane * > myFoeLanes
const std::string & getID() const
Returns the name of the vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.